예제 #1
0
    def __createScoreLabel( self, score, previousScore,
                            showFileName, fileName ):
        " Creates the score label "

        txt = "Score: " + str( score )
        if previousScore != "":
            txt += " / Previous score: " + str( previousScore )
        if not showFileName:
            txt += " for " + os.path.basename( fileName )

        scoreLabel = QLabel( txt )
        scoreLabel.setFrameShape( QFrame.StyledPanel )
        scoreLabel.setFont( self.__headerFont )
        scoreLabel.setAutoFillBackground( True )
        palette = scoreLabel.palette()

        if score < self.BadLimit:
            palette.setColor( QPalette.Background, QColor( 255, 127, 127 ) )
            palette.setColor( QPalette.Foreground, QColor( 0, 0, 0 ) )
        elif score > self.GoodLimit:
            palette.setColor( QPalette.Background, QColor( 220, 255, 220 ) )
            palette.setColor( QPalette.Foreground, QColor( 0, 0, 0 ) )
        else:
            palette.setColor( QPalette.Background, QColor( 255, 255, 127 ) )
            palette.setColor( QPalette.Foreground, QColor( 0, 0, 0 ) )

        scoreLabel.setPalette( palette )
        return scoreLabel
예제 #2
0
    def __createScoreLabel(self, score, previousScore, showFileName, fileName):
        " Creates the score label "

        txt = "Score: " + str(score)
        if previousScore != "":
            txt += " / Previous score: " + str(previousScore)
        if not showFileName:
            txt += " for " + os.path.basename(fileName)

        scoreLabel = QLabel(txt)
        scoreLabel.setFrameShape(QFrame.StyledPanel)
        scoreLabel.setFont(self.__headerFont)
        scoreLabel.setAutoFillBackground(True)
        palette = scoreLabel.palette()

        if score < self.BadLimit:
            palette.setColor(QPalette.Background, QColor(255, 127, 127))
            palette.setColor(QPalette.Foreground, QColor(0, 0, 0))
        elif score > self.GoodLimit:
            palette.setColor(QPalette.Background, QColor(220, 255, 220))
            palette.setColor(QPalette.Foreground, QColor(0, 0, 0))
        else:
            palette.setColor(QPalette.Background, QColor(255, 255, 127))
            palette.setColor(QPalette.Foreground, QColor(0, 0, 0))

        scoreLabel.setPalette(palette)
        return scoreLabel
class Option(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        Layout = QHBoxLayout(self)
        Layout.setMargin(0)
        
        self.button = Button(self)
        palette = QPalette(self.button.palette())
        palette.setColor(QPalette.Button, QColor('grey').dark(150))
        self.button.setPalette(palette)
        QObject.connect(self.button, SIGNAL('clicked()'), self.clicked)
        Layout.addWidget(self.button)
        
        self.label = QLabel(self)
        self.label.setFrameShape(QLabel.Panel)
        self.label.setFixedHeight(self.button.height())
        self.label.setAutoFillBackground(True)
        self.label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        palette = QPalette(self.label.palette())
        palette.setColor(QPalette.Window, QColor(151, 169, 0))
        self.label.setPalette(palette)
        Layout.addWidget(self.label)

    def clicked(self):
        self.emit(SIGNAL('selected(QString &)'), self.label.text())
예제 #4
0
 def addSection(self, section):
     """
     Adds a section to this menu.  A section will create a label for the
     menu to separate sections of the menu out.
     
     :param      section | <str>
     """
     label = QLabel(section, self)
     label.setMinimumHeight(self.titleHeight())
     
     # setup font
     font = label.font()
     font.setBold(True)
     
     # setup palette
     palette = label.palette()
     palette.setColor(palette.WindowText, palette.color(palette.Mid))
     
     # setup label
     label.setFont(font)
     label.setAutoFillBackground(True)
     label.setPalette(palette)
     
     # create the widget action
     action = QWidgetAction(self)
     action.setDefaultWidget(label)
     self.addAction(action)
     
     return action
class LegendWidget(Ui_legendsWidget, QWidget):
    showmap = pyqtSignal()

    def __init__(self, parent=None):
        super(LegendWidget, self).__init__(parent)
        self.setupUi(self)
        self.gridLayout = QGridLayout(self.legendList)
        self.gridLayout.setColumnStretch(0,10)
        self.gridLayout.setColumnStretch(1,300)

    def show(self,layers):
        self.dstroyLegend()
        super(LegendWidget, self).show()
        self.items = {}
        for layer in layers:
            if not layer.type() == QgsMapLayer.VectorLayer:
                continue

            try:
                items = layer.rendererV2().legendSymbologyItems(ICON_SIZE)
            except AttributeError:
                continue
            self.items[layer.name()] = items
        self.styleLegend(items)

    def styleLegend(self,items):
        i=0
        for layer, items in self.items.iteritems():
            for text, icon in items:
                if not text or text.startswith("~"):
                    continue
                self.makeLabel(text,icon,i)
                i += 1

    def makeLabel(self,text,icon,nrow):
        self.newLabel=QLabel()
        self.newLabel.setText(text)
        self.newLabel.setStyleSheet(_fromUtf8("background-color:transparent;"))
        self.newLabel.setAutoFillBackground(True)
        self.newIcon=QLabel()
        self.newIcon.setPixmap(icon)
        self.newIcon.setStyleSheet(_fromUtf8("background-color:transparent;"))
        self.newIcon.setAutoFillBackground(True)
        self.gridLayout.addWidget(self.newIcon,nrow,0,HALLIGNEMENT)
        self.gridLayout.addWidget(self.newLabel,nrow,1)


    def makeLabelLayer(self,text,nrow):
        self.newLabel=QLabel()
        self.newLabel.setText(text)
        self.gridLayout.addWidget(self.newLabel,nrow,1)

    def dstroyLegend(self):
        while self.gridLayout.count():
            self.item = self.gridLayout.itemAt(0).widget()
            self.gridLayout.removeWidget(self.item)
            self.item.deleteLater()
예제 #6
0
    def __createLayout( self ):
        " Creates the widget layout "
        totalCalls = self.__stats.total_calls
        totalPrimitiveCalls = self.__stats.prim_calls  # The calls were not induced via recursion
        totalTime = self.__stats.total_tt

        txt = "<b>Script:</b> " + self.__script + " " + self.__params.arguments + "<br>" \
              "<b>Run at:</b> " + self.__reportTime + "<br>" + \
              str( totalCalls ) + " function calls (" + \
              str( totalPrimitiveCalls ) + " primitive calls) in " + \
              FLOAT_FORMAT % totalTime + " CPU seconds"
        summary = QLabel( txt )
        summary.setToolTip( txt )
        summary.setSizePolicy( QSizePolicy.Ignored, QSizePolicy.Fixed )
        summary.setFrameStyle( QFrame.StyledPanel )
        summary.setAutoFillBackground( True )
        summaryPalette = summary.palette()
        summaryBackground = summaryPalette.color( QPalette.Background )
        summaryBackground.setRgb( min( summaryBackground.red() + 30, 255 ),
                                  min( summaryBackground.green() + 30, 255 ),
                                  min( summaryBackground.blue() + 30, 255 ) )
        summaryPalette.setColor( QPalette.Background, summaryBackground )
        summary.setPalette( summaryPalette )

        self.__scene = QGraphicsScene()
        self.__viewer = DiagramWidget()
        self.__viewer.escapePressed.connect( self.__onESC )

        vLayout = QVBoxLayout()
        vLayout.setContentsMargins( 0, 0, 0, 0 )
        vLayout.setSpacing( 0 )
        vLayout.addWidget( summary )
        vLayout.addWidget( self.__viewer )

        self.setLayout( vLayout )
        return
예제 #7
0
    def __createLayout(self):
        " Creates the widget layout "
        totalCalls = self.__stats.total_calls
        totalPrimitiveCalls = self.__stats.prim_calls  # The calls were not induced via recursion
        totalTime = self.__stats.total_tt

        txt = "<b>Script:</b> " + self.__script + " " + self.__params.arguments + "<br>" \
              "<b>Run at:</b> " + self.__reportTime + "<br>" + \
              str( totalCalls ) + " function calls (" + \
              str( totalPrimitiveCalls ) + " primitive calls) in " + \
              FLOAT_FORMAT % totalTime + " CPU seconds"
        summary = QLabel(txt)
        summary.setToolTip(txt)
        summary.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
        summary.setFrameStyle(QFrame.StyledPanel)
        summary.setAutoFillBackground(True)
        summaryPalette = summary.palette()
        summaryBackground = summaryPalette.color(QPalette.Background)
        summaryBackground.setRgb(min(summaryBackground.red() + 30, 255),
                                 min(summaryBackground.green() + 30, 255),
                                 min(summaryBackground.blue() + 30, 255))
        summaryPalette.setColor(QPalette.Background, summaryBackground)
        summary.setPalette(summaryPalette)

        self.__scene = QGraphicsScene()
        self.__viewer = DiagramWidget()
        self.__viewer.escapePressed.connect(self.__onESC)

        vLayout = QVBoxLayout()
        vLayout.setContentsMargins(0, 0, 0, 0)
        vLayout.setSpacing(0)
        vLayout.addWidget(summary)
        vLayout.addWidget(self.__viewer)

        self.setLayout(vLayout)
        return
예제 #8
0
class Tooltip(QFrame):
    " Custom tooltip "

    def __init__(self):
        QFrame.__init__(self)

        # Avoid the border around the window
        self.setWindowFlags(Qt.SplashScreen)

        # Make the frame nice looking
        self.setFrameShape(QFrame.StyledPanel)
        self.setLineWidth(2)

        self.info = None
        self.location = None
        self.__createLayout()

        # The item the tooltip is for
        self.item = None

        # The timer which shows the tooltip. The timer is controlled from
        # outside of the class.
        self.tooltipTimer = QTimer(self)
        self.tooltipTimer.setSingleShot(True)
        self.tooltipTimer.timeout.connect(self.__onTimer)

        self.startPosition = None
        return

    def __createLayout(self):
        " Creates the tooltip layout "
        verticalLayout = QVBoxLayout(self)
        self.info = QLabel()
        self.info.setAutoFillBackground(True)
        font = self.info.font()
        font.setFamily(GlobalData().skin.baseMonoFontFace)
        self.info.setFont(font)
        self.info.setFrameShape(QFrame.StyledPanel)
        verticalLayout.addWidget(self.info)
        verticalLayout.setMargin(0)
        self.location = QLabel()
        verticalLayout.addWidget(self.location)
        return

    def setText(self, text):
        " Sets the tooltip text "
        self.info.setText(text)
        return

    def setLocation(self, text):
        " Sets the file name and line at the bottom "
        self.location.setText(text)
        return

    def setModified(self, status):
        " Sets the required tooltip background "
        palette = self.info.palette()
        if status:
            # Reddish
            palette.setColor(QPalette.Background, QColor(255, 227, 227))
        else:
            # Blueish
            palette.setColor(QPalette.Background, QColor(224, 236, 255))
        self.info.setPalette(palette)
        return

    def setItem(self, item):
        " Sets the item the tooltip is shown for "
        self.item = item
        return

    def __getTooltipPos(self):
        " Calculates the tooltip position - above the row "
        pos = QCursor.pos()
        if pos.x() + self.sizeHint().width() >= screenWidth:
            pos.setX(screenWidth - self.sizeHint().width() - 2)
        pos.setY(pos.y() - cellHeight - 1 - self.sizeHint().height())
        return pos

    def __onTimer(self):
        " Triggered by the show tooltip timer "
        currentPos = QCursor.pos()
        if abs( currentPos.x() - self.startPosition.x() ) <= 2 and \
           abs( currentPos.y() - self.startPosition.y() ) <= 2:
            # No movement since last time, show the tooltip
            self.show()
            return

        # There item has not been changed, but the position within it was
        # So restart the timer, but for shorter
        self.startPosition = currentPos
        self.tooltipTimer.start(400)
        return

    def startShowTimer(self):
        " Memorizes the cursor position and starts the timer "
        self.tooltipTimer.stop()
        self.startPosition = QCursor.pos()
        self.tooltipTimer.start(500)  # 0.5 sec
        return

    def show(self):
        " Shows the tooltip at the proper position "
        QToolTip.hideText()
        QApplication.processEvents()
        if not inside:
            return
        self.move(self.__getTooltipPos())
        self.raise_()
        QFrame.show(self)
        return
예제 #9
0
class PylintViewer(QWidget):
    " Pylint tab widget "

    # Limits to colorize the final score
    BadLimit = 8.5
    GoodLimit = 9.5

    # Options of providing a report
    SingleFile = 0
    DirectoryFiles = 1
    ProjectFiles = 2
    SingleBuffer = 3

    updatePylintTooltip = pyqtSignal(str)

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

        self.__reportUUID = ""
        self.__reportFileName = ""
        self.__reportOption = -1
        self.__reportShown = False
        self.__report = None

        self.__widgets = []

        # Prepare members for reuse
        if GlobalData().pylintAvailable:
            self.__noneLabel = QLabel("\nNo results available")
        else:
            self.__noneLabel = QLabel("\nPylint is not available")
        self.__noneLabel.setAutoFillBackground(True)
        noneLabelPalette = self.__noneLabel.palette()
        noneLabelPalette.setColor(QPalette.Background,
                                  GlobalData().skin.nolexerPaper)
        self.__noneLabel.setPalette(noneLabelPalette)

        self.__noneLabel.setFrameShape(QFrame.StyledPanel)
        self.__noneLabel.setAlignment(Qt.AlignHCenter)
        self.__headerFont = self.__noneLabel.font()
        self.__headerFont.setPointSize(self.__headerFont.pointSize() + 4)
        self.__noneLabel.setFont(self.__headerFont)

        self.__createLayout(parent)

        self.__updateButtonsStatus()
        self.resizeEvent()
        return

    def __createLayout(self, parent):
        " Creates the toolbar and layout "

        # Buttons
        self.printButton = QAction(PixmapCache().getIcon('printer.png'),
                                   'Print', self)
        #printButton.setShortcut( 'Ctrl+' )
        self.printButton.triggered.connect(self.__onPrint)
        self.printButton.setVisible(False)

        self.printPreviewButton = QAction(
            PixmapCache().getIcon('printpreview.png'), 'Print preview', self)
        #printPreviewButton.setShortcut( 'Ctrl+' )
        self.printPreviewButton.triggered.connect(self.__onPrintPreview)
        self.printPreviewButton.setVisible(False)

        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.clearButton = QAction(PixmapCache().getIcon('trash.png'), 'Clear',
                                   self)
        self.clearButton.triggered.connect(self.__clear)

        # The toolbar
        self.toolbar = QToolBar(self)
        self.toolbar.setOrientation(Qt.Vertical)
        self.toolbar.setMovable(False)
        self.toolbar.setAllowedAreas(Qt.RightToolBarArea)
        self.toolbar.setIconSize(QSize(16, 16))
        self.toolbar.setFixedWidth(28)
        self.toolbar.setContentsMargins(0, 0, 0, 0)

        self.toolbar.addAction(self.printPreviewButton)
        self.toolbar.addAction(self.printButton)
        self.toolbar.addWidget(spacer)
        self.toolbar.addAction(self.clearButton)

        self.__vLayout = QVBoxLayout()
        self.__vLayout.setContentsMargins(5, 5, 5, 5)
        self.__vLayout.setSpacing(0)
        self.__vLayout.setSizeConstraint(QLayout.SetFixedSize)

        self.__bodyFrame = QFrame(self)
        #        self.__bodyFrame.setFrameShape( QFrame.StyledPanel )
        self.__bodyFrame.setFrameShape(QFrame.NoFrame)

        #        self.__bodyFrame.setSizePolicy( QSizePolicy.Maximum,
        #                                        QSizePolicy.Expanding )
        self.__bodyFrame.setLayout(self.__vLayout)
        self.bodyWidget = QScrollArea(self)
        self.bodyWidget.setFocusPolicy(Qt.NoFocus)
        self.bodyWidget.setWidget(self.__bodyFrame)
        self.bodyWidget.hide()

        self.__hLayout = QHBoxLayout()
        self.__hLayout.setContentsMargins(0, 0, 0, 0)
        self.__hLayout.setSpacing(0)
        self.__hLayout.addWidget(self.toolbar)
        self.__hLayout.addWidget(self.__noneLabel)
        self.__hLayout.addWidget(self.bodyWidget)

        self.setLayout(self.__hLayout)
        return

    def __updateButtonsStatus(self):
        " Updates the buttons status "
        self.printButton.setEnabled(self.__reportShown)
        self.printPreviewButton.setEnabled(self.__reportShown)
        self.clearButton.setEnabled(self.__reportShown)
        return

    def __onPrint(self):
        " Triggered when the print button is pressed "
        pass

    def __onPrintPreview(self):
        " triggered when the print preview button is pressed "
        pass

    def setFocus(self):
        " Overridden setFocus "
        self.__vLayout.setFocus()
        return

    def __clear(self):
        " Clears the content of the vertical layout "
        if not self.__reportShown:
            return

        self.__removeAll()
        self.bodyWidget.hide()
        self.__noneLabel.show()

        self.__report = None
        self.__reportShown = False
        self.__updateButtonsStatus()
        self.resizeEvent()

        self.__updateTooltip()
        return

    def __removeAll(self):
        " Removes all the items from the report "
        for item in self.__widgets:
            item.hide()
            self.__vLayout.removeWidget(item)
            del item

        self.__widgets = []
        return

    def __createScoreLabel(self, score, previousScore, showFileName, fileName):
        " Creates the score label "

        txt = "Score: " + str(score)
        if previousScore != "":
            txt += " / Previous score: " + str(previousScore)
        if not showFileName:
            txt += " for " + os.path.basename(fileName)

        scoreLabel = QLabel(txt)
        scoreLabel.setFrameShape(QFrame.StyledPanel)
        scoreLabel.setFont(self.__headerFont)
        scoreLabel.setAutoFillBackground(True)
        palette = scoreLabel.palette()

        if score < self.BadLimit:
            palette.setColor(QPalette.Background, QColor(255, 127, 127))
            palette.setColor(QPalette.Foreground, QColor(0, 0, 0))
        elif score > self.GoodLimit:
            palette.setColor(QPalette.Background, QColor(220, 255, 220))
            palette.setColor(QPalette.Foreground, QColor(0, 0, 0))
        else:
            palette.setColor(QPalette.Background, QColor(255, 255, 127))
            palette.setColor(QPalette.Foreground, QColor(0, 0, 0))

        scoreLabel.setPalette(palette)
        return scoreLabel

    @staticmethod
    def __setTableHeight(table):
        " Auxiliary function to set the table height "

        # Height - it is ugly and approximate however I am tired of
        # calculating the proper height. Why is this so hard, huh?
        lastRowHeight = table.itemDelegate().lastHeight
        height = lastRowHeight * (table.topLevelItemCount() + 1) + 10
        table.setFixedHeight(height)
        return

    @staticmethod
    def __shouldShowFileName(messages):
        " Decides if the file name column should be supressed "
        if len(messages) == 0:
            return False
        firstName = messages[0].fileName
        for index in range(1, len(messages)):
            if firstName != messages[index].fileName:
                return True
        return False

    def __addErrorsTable(self, messages, showFileName):
        " Creates the messages table "

        errTable = QTreeWidget(self.bodyWidget)
        errTable.setAlternatingRowColors(True)
        errTable.setRootIsDecorated(False)
        errTable.setItemsExpandable(False)
        errTable.setSortingEnabled(True)
        errTable.setItemDelegate(NoOutlineHeightDelegate(4))
        errTable.setUniformRowHeights(True)
        errTable.itemActivated.connect(self.__errorActivated)

        headerLabels = ["File name", "Line", "Message ID", "Object", "Message"]
        errTable.setHeaderLabels(headerLabels)

        for item in messages:
            if item.position is None:
                lineNumber = str(item.lineNumber)
            else:
                lineNumber = str(item.lineNumber) + ":" + str(item.position)
            values = [
                item.fileName, lineNumber, item.messageID, item.objectName,
                item.message
            ]
            errTable.addTopLevelItem(ErrorTableItem(values, 1))

        # Hide the file name column if required
        if not showFileName:
            errTable.setColumnHidden(0, True)

        # Resizing
        errTable.header().resizeSections(QHeaderView.ResizeToContents)
        errTable.header().setStretchLastSection(True)

        # Sort indicator
        if showFileName:
            sortIndex = 0  # By file names
        else:
            sortIndex = 1  # By line number because this is from the same file
        errTable.header().setSortIndicator(sortIndex, Qt.AscendingOrder)
        errTable.sortItems(sortIndex, errTable.header().sortIndicatorOrder())

        # Height
        self.__setTableHeight(errTable)

        self.__vLayout.addWidget(errTable)
        self.__widgets.append(errTable)
        return

    def __addSimilarity(self, similarity, titleText):
        " Adds a similarity "

        # Label
        title = QLabel(titleText)
        title.setFont(self.__headerFont)

        self.__vLayout.addWidget(title)
        self.__widgets.append(title)

        # List of files
        simTable = QTreeWidget(self.bodyWidget)
        simTable.setAlternatingRowColors(True)
        simTable.setRootIsDecorated(False)
        simTable.setItemsExpandable(False)
        simTable.setSortingEnabled(False)
        simTable.setItemDelegate(NoOutlineHeightDelegate(4))
        simTable.setUniformRowHeights(True)
        simTable.itemActivated.connect(self.__similarityActivated)
        simTable.setHeaderLabels(["File name", "Line"])

        for item in similarity.files:
            values = [item[0], str(item[1])]
            simTable.addTopLevelItem(QTreeWidgetItem(values))

        # Resizing
        simTable.header().resizeSections(QHeaderView.ResizeToContents)
        simTable.header().setStretchLastSection(True)

        # Height
        self.__setTableHeight(simTable)

        self.__vLayout.addWidget(simTable)
        self.__widgets.append(simTable)

        # The fragment itself
        if len(similarity.fragment) > 10:
            # Take first 9 lines
            text = "\n".join(similarity.fragment[:9]) + "\n ..."
            toolTip = "\n".join(similarity.fragment)
        else:
            text = "\n".join(similarity.fragment)
            toolTip = ""
        fragmentLabel = QLabel("<pre>" + self.__htmlEncode(text) + "</pre>")
        if toolTip != "":
            fragmentLabel.setToolTip("<pre>" + self.__htmlEncode(toolTip) +
                                     "</pre>")
        palette = fragmentLabel.palette()
        palette.setColor(QPalette.Background, QColor(250, 250, 175))
        palette.setColor(QPalette.Foreground, QColor(0, 0, 0))
        fragmentLabel.setPalette(palette)
        fragmentLabel.setFrameShape(QFrame.StyledPanel)
        fragmentLabel.setAutoFillBackground(True)

        labelFont = fragmentLabel.font()
        labelFont.setFamily(GlobalData().skin.baseMonoFontFace)
        fragmentLabel.setFont(labelFont)

        self.__vLayout.addWidget(fragmentLabel)
        self.__widgets.append(fragmentLabel)
        return

    @staticmethod
    def __htmlEncode(string):
        " Encodes HTML "
        return string.replace( "&", "&amp;" ) \
                     .replace( ">", "&gt;" ) \
                     .replace( "<", "&lt;" )

    def __addSectionSpacer(self):
        " Adds a fixed height spacer to the VBox layout "
        spacer = QWidget()
        spacer.setFixedHeight(10)
        self.__vLayout.addWidget(spacer)
        self.__widgets.append(spacer)
        return

    def __addGenericTable(self, table):
        " Adds a generic table to the report "

        theTable = QTreeWidget(self.bodyWidget)
        theTable.setAlternatingRowColors(True)
        theTable.setRootIsDecorated(False)
        theTable.setItemsExpandable(False)
        theTable.setSortingEnabled(False)
        theTable.setItemDelegate(NoOutlineHeightDelegate(4))
        theTable.setUniformRowHeights(True)

        headerLabels = []
        for index in range(0, len(table.header)):
            headerLabels.append(table.header[index])
        theTable.setHeaderLabels(headerLabels)

        for item in table.body:
            row = []
            for index in range(0, len(table.header)):
                row.append(item[index])
            theTable.addTopLevelItem(QTreeWidgetItem(row))

        theTable.setFocusPolicy(Qt.NoFocus)

        # Resizing
        theTable.header().resizeSections(QHeaderView.ResizeToContents)
        theTable.header().setStretchLastSection(True)

        # Height
        self.__setTableHeight(theTable)

        self.__vLayout.addWidget(theTable)
        self.__widgets.append(theTable)
        return

    def __addGenericTableTitle(self, table):
        " Adds a generic table title "
        tableTitle = QLabel(table.title)
        tableTitle.setFont(self.__headerFont)

        self.__vLayout.addWidget(tableTitle)
        self.__widgets.append(tableTitle)
        return

    def __updateTooltip(self):
        " Generates a signal with appropriate string message "
        if not self.__reportShown:
            tooltip = "No results available"
        elif self.__reportOption == self.DirectoryFiles:
            tooltip = "Report generated for directory: " + \
                      self.__reportFileName
        elif self.__reportOption == self.ProjectFiles:
            tooltip = "Report generated for the whole project"
        elif self.__reportOption == self.SingleFile:
            tooltip = "Report generated for file: " + self.__reportFileName
        elif self.__reportOption == self.SingleBuffer:
            tooltip = "Report generated for unsaved file: " + \
                      self.__reportFileName
        else:
            tooltip = ""
        self.updatePylintTooltip.emit(tooltip)
        return

    def showReport(self, lint, reportOption, fileName, uuid):
        " Shows the pylint results "
        self.__removeAll()
        self.__noneLabel.hide()

        self.__report = lint
        self.__reportUUID = uuid
        self.__reportFileName = fileName
        self.__reportOption = reportOption

        showFileName = self.__shouldShowFileName(lint.errorMessages)

        scoreLabel = self.__createScoreLabel(lint.score, lint.previousScore,
                                             showFileName, fileName)
        self.__vLayout.addWidget(scoreLabel)
        self.__widgets.append(scoreLabel)

        if len(lint.errorMessages) > 0:
            self.__addSectionSpacer()
            self.__addErrorsTable(lint.errorMessages, showFileName)

        index = 0
        for similarity in lint.similarities:
            self.__addSectionSpacer()
            self.__addSimilarity(similarity, "Similarity #" + str(index))
            index += 1

        for table in lint.tables:
            self.__addSectionSpacer()
            self.__addGenericTableTitle(table)
            self.__addGenericTable(table)

        self.bodyWidget.show()
        self.bodyWidget.ensureVisible(0, 0, 0, 0)
        self.__reportShown = True
        self.__updateButtonsStatus()
        self.__updateTooltip()

        # It helps, but why do I have flickering?
        QApplication.processEvents()
        self.__resizeBodyFrame()
        return

    def __errorActivated(self, item, column):
        " Handles the double click (or Enter) on the item "

        linePos = str(item.text(1))
        if ":" in linePos:
            parts = linePos.split(":")
            lineNumber = int(parts[0])
            pos = int(parts[1])
        else:
            lineNumber = int(linePos)
            pos = 0

        if self.__reportOption in [
                self.SingleFile, self.DirectoryFiles, self.ProjectFiles
        ]:
            fileName = str(item.text(0))
        else:
            # SingleBuffer
            if self.__reportFileName != "":
                if os.path.isabs(self.__reportFileName):
                    fileName = self.__reportFileName
                else:
                    # Could be unsaved buffer, so try to search by the
                    mainWindow = GlobalData().mainWindow
                    widget = mainWindow.getWidgetByUUID(self.__reportUUID)
                    if widget is None:
                        logging.error("The unsaved buffer has been closed")
                        return
                    # The widget was found, so jump to the required
                    editor = widget.getEditor()
                    editor.gotoLine(lineNumber, pos)
                    editor.setFocus()
                    return

        GlobalData().mainWindow.openFile(fileName, lineNumber, pos)
        return

    def __resizeBodyFrame(self):
        " Resizing the frame to occupy all available width "
        size = self.bodyWidget.maximumViewportSize()
        self.__bodyFrame.setMinimumWidth(size.width() - 16)
        self.__bodyFrame.setMinimumHeight(size.height())
        return

    def showEvent(self, showEv=None):
        " Called when the widget is shown "
        self.__resizeBodyFrame()
        return

    def resizeEvent(self, resizeEv=None):
        " Called when the main window gets resized "
        self.__resizeBodyFrame()
        return

    def onFileUpdated(self, fileName, uuid):
        " Called when a buffer is saved or saved as "

        if not self.__reportShown:
            return
        if self.__reportUUID != uuid:
            return

        # Currently shown report is for the saved buffer
        # File name is expected being absolute
        self.__reportFileName = fileName
        self.updatePylintTooltip.emit("Report generated for buffer saved as " +
                                      fileName)
        return

    def __similarityActivated(self, item, column):
        " Triggered when a similarity is activated "
        fileName = str(item.text(0))
        lineNumber = int(item.text(1))
        GlobalData().mainWindow.openFile(fileName, lineNumber)
        return
예제 #10
0
    def __addSimilarity(self, similarity, titleText):
        " Adds a similarity "

        # Label
        title = QLabel(titleText)
        title.setFont(self.__headerFont)

        self.__vLayout.addWidget(title)
        self.__widgets.append(title)

        # List of files
        simTable = QTreeWidget(self.bodyWidget)
        simTable.setAlternatingRowColors(True)
        simTable.setRootIsDecorated(False)
        simTable.setItemsExpandable(False)
        simTable.setSortingEnabled(False)
        simTable.setItemDelegate(NoOutlineHeightDelegate(4))
        simTable.setUniformRowHeights(True)
        simTable.itemActivated.connect(self.__similarityActivated)
        simTable.setHeaderLabels(["File name", "Line"])

        for item in similarity.files:
            values = [item[0], str(item[1])]
            simTable.addTopLevelItem(QTreeWidgetItem(values))

        # Resizing
        simTable.header().resizeSections(QHeaderView.ResizeToContents)
        simTable.header().setStretchLastSection(True)

        # Height
        self.__setTableHeight(simTable)

        self.__vLayout.addWidget(simTable)
        self.__widgets.append(simTable)

        # The fragment itself
        if len(similarity.fragment) > 10:
            # Take first 9 lines
            text = "\n".join(similarity.fragment[:9]) + "\n ..."
            toolTip = "\n".join(similarity.fragment)
        else:
            text = "\n".join(similarity.fragment)
            toolTip = ""
        fragmentLabel = QLabel("<pre>" + self.__htmlEncode(text) + "</pre>")
        if toolTip != "":
            fragmentLabel.setToolTip("<pre>" + self.__htmlEncode(toolTip) +
                                     "</pre>")
        palette = fragmentLabel.palette()
        palette.setColor(QPalette.Background, QColor(250, 250, 175))
        palette.setColor(QPalette.Foreground, QColor(0, 0, 0))
        fragmentLabel.setPalette(palette)
        fragmentLabel.setFrameShape(QFrame.StyledPanel)
        fragmentLabel.setAutoFillBackground(True)

        labelFont = fragmentLabel.font()
        labelFont.setFamily(GlobalData().skin.baseMonoFontFace)
        fragmentLabel.setFont(labelFont)

        self.__vLayout.addWidget(fragmentLabel)
        self.__widgets.append(fragmentLabel)
        return
예제 #11
0
    def __init__( self, scriptName, params, reportTime,
                        dataFile, stats, parent = None ):
        QWidget.__init__( self, parent )

        self.__table = ProfilerTreeWidget( self )
        self.__table.escapePressed.connect( self.__onEsc )

        self.__script = scriptName
        self.__stats = stats
        project = GlobalData().project
        if project.isLoaded():
            self.__projectPrefix = os.path.dirname( project.fileName )
        else:
            self.__projectPrefix = os.path.dirname( scriptName )
        if not self.__projectPrefix.endswith( os.path.sep ):
            self.__projectPrefix += os.path.sep

        self.__table.setAlternatingRowColors( True )
        self.__table.setRootIsDecorated( False )
        self.__table.setItemsExpandable( False )
        self.__table.setSortingEnabled( True )
        self.__table.setItemDelegate( NoOutlineHeightDelegate( 4 ) )
        self.__table.setUniformRowHeights( True )
        self.__table.setSelectionMode( QAbstractItemView.SingleSelection )
        self.__table.setSelectionBehavior( QAbstractItemView.SelectRows )

        headerLabels = [ "", "Calls", "Total time", "Per call",
                         "Cum. time", "Per call", "File name:line",
                         "Function", "Callers", "Callees" ]
        self.__table.setHeaderLabels( headerLabels )

        headerItem = self.__table.headerItem()
        headerItem.setToolTip( 0, "Indication if it is an outside function" )
        headerItem.setToolTip( 1, "Actual number of calls/primitive calls "
                                  "(not induced via recursion)" )
        headerItem.setToolTip( 2, "Total time spent in function "
                                  "(excluding time made in calls "
                                  "to sub-functions)" )
        headerItem.setToolTip( 3, "Total time divided by number "
                                  "of actual calls" )
        headerItem.setToolTip( 4, "Total time spent in function and all "
                                  "subfunctions (from invocation till exit)" )
        headerItem.setToolTip( 5, "Cumulative time divided by number "
                                  "of primitive calls" )
        headerItem.setToolTip( 6, "Function location" )
        headerItem.setToolTip( 7, "Function name" )
        headerItem.setToolTip( 8, "Function callers" )
        headerItem.setToolTip( 9, "Function callees" )

        self.__table.itemActivated.connect( self.__activated )

        totalCalls = self.__stats.total_calls
        totalPrimitiveCalls = self.__stats.prim_calls  # The calls were not induced via recursion
        totalTime = self.__stats.total_tt

        txt = "<b>Script:</b> " + self.__script + " " + params.arguments + "<br>" \
              "<b>Run at:</b> " + reportTime + "<br>" + \
              str( totalCalls ) + " function calls (" + \
              str( totalPrimitiveCalls ) + " primitive calls) in " + \
              FLOAT_FORMAT % totalTime + " CPU seconds"
        summary = QLabel( txt )
        summary.setToolTip( txt )
        summary.setSizePolicy( QSizePolicy.Ignored, QSizePolicy.Fixed )
        summary.setFrameStyle( QFrame.StyledPanel )
        summary.setAutoFillBackground( True )
        summaryPalette = summary.palette()
        summaryBackground = summaryPalette.color( QPalette.Background )
        summaryBackground.setRgb( min( summaryBackground.red() + 30, 255 ),
                                  min( summaryBackground.green() + 30, 255 ),
                                  min( summaryBackground.blue() + 30, 255 ) )
        summaryPalette.setColor( QPalette.Background, summaryBackground )
        summary.setPalette( summaryPalette )

        vLayout = QVBoxLayout()
        vLayout.setContentsMargins( 0, 0, 0, 0 )
        vLayout.setSpacing( 0 )
        vLayout.addWidget( summary )
        vLayout.addWidget( self.__table )

        self.setLayout( vLayout )
        self.__createContextMenu()

        self.__populate( totalTime )
        return
예제 #12
0
파일: scj.py 프로젝트: Ptaah/SCJ
class QtSCJ(QDialog) :
    """
    QtSCJ est une boite de dialogue contenant l'état de la progression de 
    chaque processus
    """

    def __init__(self, parent=None):
        super(QtSCJ, self).__init__(parent)
        self.dir = None
        self.jobs = { }
        self.log = [ ]
        self.mode = "ogg"
        self.filter = "*.mp3 *.ogg *.wav"
        self.modes = [ "ogg", "mp3", "wav" ]

        self.readSettings()

        self.setupUi()
        self.retranslateUi()
        self.fermer.setEnabled(True)
        
        self.connect(self.fermer,SIGNAL("clicked()"),self.close)
        self.connect(self.convertDir,SIGNAL("clicked()"),self.getDir)
        self.connect(self.convertFile,SIGNAL("clicked()"),self.getFiles)
        self.connect(self.startallbtn,SIGNAL("clicked()"),self.startAll)
        self.connect(self.delallbtn,SIGNAL("clicked()"),self.delAll)
        self.connect(self.output,SIGNAL("currentIndexChanged(const QString)"),
                     self.setMode)

    def setMode(self, mode):
        self.mode = mode
        self.writeSettings()

    def writeSettings(self):
        settings = QSettings("scj", "scj")
        settings.setValue("mode", self.mode)

    def readSettings(self):
        settings = QSettings("scj", "scj")
        self.mode = settings.value("mode", "ogg").toString()

    def setupUi(self):
        self.setObjectName("SCJ")
        self.setFixedSize(600,260)
        #self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.verticalLayout = QVBoxLayout(self)
        self.verticalLayout.setObjectName("verticalLayout")
        #self.infoText = QTextEdit(self)
        self.infoText = QLabel(self)
        palette = QPalette()
        brush = QBrush(QColor(245, 245, 245))
        brush.setStyle(Qt.SolidPattern)
        palette.setBrush(QPalette.Normal, QPalette.Background, brush)
        self.infoText.setPalette(palette)
        self.infoText.setAutoFillBackground(True)
        self.infoText.setFixedHeight(200)
        self.infoText.setObjectName("infoText")
        #self.infoText.setReadOnly(True)
        self.infoText.setWordWrap(True)
        self.verticalLayout.addWidget(self.infoText)
        # Manage Actions buttons
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                 QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        ## Format de sortie
        self.outlabel = QLabel(self.trUtf8("Choix du format de destination"))
        self.horizontalLayout.addWidget(self.outlabel)
        self.output = QComboBox()
        self.output.addItems(self.modes)
        self.output.setCurrentIndex(self.output.findText(self.mode))
        self.horizontalLayout.addWidget(self.output)
        # Buttons
        self.fermer = QPushButton(self)
        self.fermer.setObjectName("fermer")
        self.horizontalLayout.addWidget(self.fermer)
        self.convertDir = QPushButton(self)
        self.convertDir.setObjectName("convertDir")
        self.horizontalLayout.addWidget(self.convertDir)
        self.convertFile = QPushButton(self)
        self.convertFile.setObjectName("convertFile")
        self.horizontalLayout.addWidget(self.convertFile)
        self.verticalLayout.addLayout(self.horizontalLayout)

        # Layout for allButtons
        self.allLayout = QHBoxLayout()
        # Add startAll bouton
        self.startallbtn = QPushButton(self)
        self.allLayout.addWidget(self.startallbtn)
        self.startallbtn.hide()
        self.verticalLayout.addLayout(self.allLayout)
        # Add delAll bouton
        self.delallbtn = QPushButton(self)
        self.allLayout.addWidget(self.delallbtn)
        self.delallbtn.hide()
        # Mode avec scroll
        self.frame = QFrame()
        self.frame.setMinimumSize(520,250)
        self.frame.setMaximumWidth(520)
        self.scroll = QScrollArea()
        self.scroll.setMinimumHeight(180)
        self.jobsLayout = QVBoxLayout(self.frame)
        self.jobsLayout.setSizeConstraint(QLayout.SetMinAndMaxSize)
        #self.jobsLayout.setSizeConstraint(QLayout.SetMinimumSize)
        #self.jobsLayout.setSizeConstraint(QLayout.SetMaximumSize)
        self.scroll.setWidget(self.frame)
        self.scroll.setWidgetResizable(False)
        self.verticalLayout.addWidget(self.scroll)
        self.scroll.hide()

        # Mode sans scroll
        #self.jobsLayout = QVBoxLayout()
        #self.verticalLayout.addLayout(self.jobsLayout)

        # Add a strech to the bottom of the window
        self.verticalLayout.insertStretch(-1)

    def retranslateUi(self):
        self.setWindowTitle(u"SCJ")
        self.infoText.setToolTip(self.trUtf8("Messages"))
        self.fermer.setToolTip(self.trUtf8("Fermer la fenetre"))
        self.fermer.setText(self.trUtf8("Fermer"))
        self.startallbtn.setToolTip(self.trUtf8("Demarrer toutes les taches"))
        self.startallbtn.setText(self.trUtf8("Tout demarrer"))
        self.delallbtn.setToolTip(self.trUtf8("Supprimmer toutes les taches"))
        self.delallbtn.setText(self.trUtf8("Tout supprimer"))
        self.convertDir.setToolTip(self.trUtf8("Convertir un repertoire"))
        self.convertDir.setText(self.trUtf8("Repertoire"))
        self.convertFile.setToolTip(self.trUtf8("Convertir un fichier"))
        self.convertFile.setText(self.trUtf8("Fichier(s)"))
        self.infoText.setText(u"<h1>%s</h1>\
                                \n%s<br/>\
                                \n%s\
                                \n<ul><li>%s</li>\
                                \n    <li>%s</li>\
                                \n    <li><b>%s</b></li>\
                                \n</ul>" %
                (self.trUtf8("BIENVENUE SUR SCJ"),
                 self.trUtf8("SCJ permet de convertir un ou plusieurs fichiers"+
                              " son vers differents formats."),
                 self.trUtf8("Il gere egalement les repertoires en convertissant"+
                              " l'ensemble des fichiers sons presents vers le"+
                              " format voulu."),
                 self.trUtf8("Choisissez le format de destination"),
                 self.trUtf8("Cliquez sur Fichier(s) ou Repertoire en fonction"+
                             " de ve que vous voulez convertir."),
                 self.trUtf8("Demarrez la conversion !")
                ))

    def addFile(self, file, createDir=False):
        file.makeAbsolute()
        if (file.suffix() != self.mode):
            job = SCJProgress( parent=None,
                                     file=file.filePath(),
                                     format=self.mode,
                                     createDir=createDir)
            if not self.jobs.get(job.output):
                self.jobs[job.output] = job
                self.jobsLayout.addLayout(self.jobs[job.output])
                self.connect(self.jobs[job.output], SIGNAL("void removed(QString)"), self.delFile)
        self.addStartAll()

    def delFile(self, job):
        j = self.jobs.pop(job)
        self.addStartAll()
        self.jobsLayout.removeItem(j)

    def getDir(self):
        self.dir = QFileDialog.getExistingDirectory(
                                parent = self,
                                caption = self.trUtf8("Choix du repertoire"),
					            directory = QDir.homePath(),
		                        options = QFileDialog.ShowDirsOnly |
                                QFileDialog.DontResolveSymlinks)
        if self.dir :
            directory = QDir(self.dir, self.filter)
            for file in directory.entryInfoList():
                self.addFile(file, createDir=True)

    def getFiles(self):
        files = QFileDialog.getOpenFileNames(
                                parent = self,
                                caption = self.trUtf8("Choix des fichiers"),
                                directory = QDir.homePath(),
                                filter = u"%s (%s)" % (self.trUtf8("Sons"),
                                                       self.filter))
        for file in files:
            self.addFile(QFileInfo(file), createDir=False)

    def addStartAll(self):
        if (len(self.jobs) > 0 ):
            self.startallbtn.setVisible(True)
            self.delallbtn.setVisible(True)
            self.scroll.setVisible(True)
            self.setFixedSize(600, 480)
        else:
            self.startallbtn.setVisible(False)
            self.delallbtn.setVisible(False)
            self.scroll.setVisible(False)
            self.setFixedSize(600, 260)
        self.updateGeometry()

    def startAll(self):
        for (key, job) in self.jobs.items():
            job.start()

    def delAll(self):
        for (key, job) in self.jobs.items():
            job.stop()
            self.delFile(key)

    def close(self):
        print u"%s" % self.trUtf8("We are stopping running jobs"),
        for (key, job) in self.jobs.items():
            job.stop()
            print ".",
        print u"%s" % self.trUtf8("Done")
        super(QtSCJ, self).close()
예제 #13
0
class PymetricsViewer(QWidget):
    " Pymetrics tab widget "

    # Limits to colorize the McCabe score
    LittleRiskLimit = 10
    ModerateRiskLimit = 20
    HighRiskLimit = 50

    # Options of providing a report
    SingleFile = 0
    DirectoryFiles = 1
    ProjectFiles = 2
    SingleBuffer = 3

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

        self.__reportUUID = ""
        self.__reportFileName = ""
        self.__reportOption = -1
        self.__reportShown = False
        self.__report = None

        # Prepare members for reuse
        self.__noneLabel = QLabel("\nNo results available")

        self.__noneLabel.setFrameShape(QFrame.StyledPanel)
        self.__noneLabel.setAlignment(Qt.AlignHCenter)
        self.__headerFont = self.__noneLabel.font()
        self.__headerFont.setPointSize(self.__headerFont.pointSize() + 4)
        self.__noneLabel.setFont(self.__headerFont)
        self.__noneLabel.setAutoFillBackground(True)
        noneLabelPalette = self.__noneLabel.palette()
        noneLabelPalette.setColor(QPalette.Background,
                                  GlobalData().skin.nolexerPaper)
        self.__noneLabel.setPalette(noneLabelPalette)

        self.__createLayout(parent)

        self.__updateButtonsStatus()
        return

    def __createLayout(self, parent):
        " Creates the toolbar and layout "

        # Buttons
        self.__mcCabeButton = QAction(PixmapCache().getIcon('tableview.png'),
                                      'Switch to McCabe only table view', self)
        self.__mcCabeButton.setCheckable(True)
        self.connect(self.__mcCabeButton, SIGNAL('toggled(bool)'),
                     self.__onMcCabe)

        self.printButton = QAction(PixmapCache().getIcon('printer.png'),
                                   'Print', self)
        #printButton.setShortcut( 'Ctrl+' )
        self.connect(self.printButton, SIGNAL('triggered()'), self.__onPrint)
        self.printButton.setVisible(False)

        self.printPreviewButton = QAction(
            PixmapCache().getIcon('printpreview.png'), 'Print preview', self)
        #printPreviewButton.setShortcut( 'Ctrl+' )
        self.connect(self.printPreviewButton, SIGNAL('triggered()'),
                     self.__onPrintPreview)
        self.printPreviewButton.setVisible(False)

        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.clearButton = QAction(PixmapCache().getIcon('trash.png'), 'Clear',
                                   self)
        self.connect(self.clearButton, SIGNAL('triggered()'), self.__clear)

        # The toolbar
        self.toolbar = QToolBar(self)
        self.toolbar.setOrientation(Qt.Vertical)
        self.toolbar.setMovable(False)
        self.toolbar.setAllowedAreas(Qt.RightToolBarArea)
        self.toolbar.setIconSize(QSize(16, 16))
        self.toolbar.setFixedWidth(28)
        self.toolbar.setContentsMargins(0, 0, 0, 0)

        self.toolbar.addAction(self.__mcCabeButton)
        self.toolbar.addAction(self.printPreviewButton)
        self.toolbar.addAction(self.printButton)
        self.toolbar.addWidget(spacer)
        self.toolbar.addAction(self.clearButton)

        self.__totalResultsTree = QTreeWidget()
        self.__totalResultsTree.setAlternatingRowColors(True)
        self.__totalResultsTree.setRootIsDecorated(True)
        self.__totalResultsTree.setItemsExpandable(True)
        self.__totalResultsTree.setUniformRowHeights(True)
        self.__totalResultsTree.setItemDelegate(NoOutlineHeightDelegate(4))
        headerLabels = ["Path / name", "Value", ""]
        self.__totalResultsTree.setHeaderLabels(headerLabels)
        self.connect(self.__totalResultsTree,
                     SIGNAL("itemActivated(QTreeWidgetItem *, int)"),
                     self.__allItemActivated)
        self.connect(self.__totalResultsTree,
                     SIGNAL("itemExpanded(QTreeWidgetItem *)"),
                     self.__onResultsExpanded)
        self.__totalResultsTree.setColumnHidden(2, True)
        self.__totalResultsTree.hide()

        self.__mcCabeTable = QTreeWidget()
        self.__mcCabeTable.setAlternatingRowColors(True)
        self.__mcCabeTable.setRootIsDecorated(False)
        self.__mcCabeTable.setItemsExpandable(False)
        self.__mcCabeTable.setSortingEnabled(True)
        self.__mcCabeTable.setItemDelegate(NoOutlineHeightDelegate(4))
        self.__mcCabeTable.setUniformRowHeights(True)
        headerLabels = ["", "File name", "Object", "McCabe Complexity"]
        self.__mcCabeTable.setHeaderLabels(headerLabels)
        self.connect(self.__mcCabeTable,
                     SIGNAL("itemActivated(QTreeWidgetItem *, int)"),
                     self.__mcCabeActivated)
        self.__mcCabeTable.hide()

        self.__hLayout = QHBoxLayout()
        self.__hLayout.setContentsMargins(0, 0, 0, 0)
        self.__hLayout.setSpacing(0)
        self.__hLayout.addWidget(self.toolbar)
        self.__hLayout.addWidget(self.__noneLabel)
        self.__hLayout.addWidget(self.__totalResultsTree)
        self.__hLayout.addWidget(self.__mcCabeTable)

        self.setLayout(self.__hLayout)
        return

    def getTotalResultsWidget(self):
        " Provides a reference to the total results widget "
        return self.__totalResultsTree

    def getMcCabeResultsWidget(self):
        " Provides a reference to the McCabe results widget "
        return self.__mcCabeTable

    def __updateButtonsStatus(self):
        " Updates the buttons status "
        self.__mcCabeButton.setEnabled(self.__reportShown)
        self.printButton.setEnabled(self.__reportShown)
        self.printPreviewButton.setEnabled(self.__reportShown)
        self.clearButton.setEnabled(self.__reportShown)
        return

    def __onResultsExpanded(self, item):
        " An item has been expanded, so the column width should be adjusted "
        self.__totalResultsTree.header().resizeSections(
            QHeaderView.ResizeToContents)
        return

    def __onPrint(self):
        " Triggered when the print button is pressed "
        pass

    def __onPrintPreview(self):
        " triggered when the print preview button is pressed "
        pass

    def __onMcCabe(self, state):
        " Triggered when the metrics view is switched "

        if not self.__reportShown:
            return

        if state:
            self.__totalResultsTree.hide()
            self.__mcCabeTable.show()
            self.__mcCabeButton.setIcon(PixmapCache().getIcon('treeview.png'))
            self.__mcCabeButton.setToolTip("Switch to complete "
                                           "results tree view")
        else:
            self.__mcCabeTable.hide()
            self.__totalResultsTree.show()
            self.__mcCabeButton.setIcon(PixmapCache().getIcon('tableview.png'))
            self.__mcCabeButton.setToolTip("Switch to McCabe only table view")
        return

    def setFocus(self):
        " Overridden setFocus "
        self.__hLayout.setFocus()
        return

    def __clear(self):
        " Clears the content of the vertical layout "
        if not self.__reportShown:
            return

        self.__totalResultsTree.clear()
        self.__totalResultsTree.hide()
        self.__mcCabeTable.clear()
        self.__mcCabeTable.hide()
        self.__noneLabel.show()

        self.__report = None
        self.__reportShown = False
        self.__updateButtonsStatus()
        #        self.resizeEvent()
        self.__mcCabeButton.setIcon(PixmapCache().getIcon('tableview.png'))
        self.__mcCabeButton.setToolTip("Switch to McCabe only table view")
        self.__mcCabeButton.setChecked(False)

        self.__updateTooltip()
        return

    def __updateTooltip(self):
        " Generates a signal with appropriate string message "
        if not self.__reportShown:
            tooltip = "No metrics available"
        elif self.__reportOption == self.DirectoryFiles:
            tooltip = "Metrics generated for directory: " + \
                      self.__reportFileName
        elif self.__reportOption == self.ProjectFiles:
            tooltip = "Metrics generated for the whole project"
        elif self.__reportOption == self.SingleFile:
            tooltip = "Metrics generated for file: " + self.__reportFileName
        elif self.__reportOption == self.SingleBuffer:
            tooltip = "Metrics generated for unsaved file: " + \
                      self.__reportFileName
        else:
            tooltip = ""
        self.emit(SIGNAL('updatePymetricsTooltip'), tooltip)
        return

    @staticmethod
    def __shouldShowFileName(table, column):
        " Checks if the file name is the same "

        size = table.topLevelItemCount()
        if size == 0:
            return False

        index = size - 1
        firstName = table.topLevelItem(index).text(column)
        index -= 1
        while index >= 0:
            if table.topLevelItem(index).text(column) != firstName:
                return True
            index -= 1
        return False

    def showReport(self, metrics, reportOption, fileName, uuid):
        " Shows the pymetrics results "
        self.__clear()
        self.__noneLabel.hide()

        self.__report = metrics
        self.__reportUUID = uuid
        self.__reportFileName = fileName
        self.__reportOption = reportOption

        if len(metrics.report) > 1:
            accumulatedBasic = self.__accumulateBasicMetrics()
            accItem = QTreeWidgetItem(["Cumulative basic metrics"])
            self.__totalResultsTree.addTopLevelItem(accItem)
            for key in accumulatedBasic:
                bmItem = [
                    BasicMetrics.metricsOfInterest[key],
                    splitThousands(str(accumulatedBasic[key]))
                ]
                basicMetric = QTreeWidgetItem(bmItem)
                accItem.addChild(basicMetric)

        # Add the complete information
        for fileName in metrics.report:
            if reportOption == self.SingleBuffer:
                fileItem = QTreeWidgetItem(["Editor buffer"])
            else:
                fileItem = QTreeWidgetItem([fileName])
                info = GlobalData().briefModinfoCache.get(fileName)
                if info.docstring is not None:
                    fileItem.setToolTip(0, info.docstring.text)
                else:
                    fileItem.setToolTip(0, "")
            self.__totalResultsTree.addTopLevelItem(fileItem)

            # Messages part
            messages = metrics.report[fileName].messages
            if len(messages) > 0:
                messagesItem = QTreeWidgetItem(["Messages"])
                fileItem.addChild(messagesItem)
                for message in messages:
                    mItem = [message, "", "E"]
                    messagesItem.addChild(QTreeWidgetItem(mItem))

            # Basic metrics part
            basicItem = QTreeWidgetItem(["Basic metrics"])
            fileItem.addChild(basicItem)
            basic = metrics.report[fileName].basicMetrics
            for key in basic.metrics:
                bmItem = [
                    BasicMetrics.metricsOfInterest[key],
                    str(basic.metrics[key])
                ]
                basicMetric = QTreeWidgetItem(bmItem)
                basicItem.addChild(basicMetric)

            # McCabe part
            mccabeItem = QTreeWidgetItem(["McCabe metrics"])
            fileItem.addChild(mccabeItem)
            mccabe = metrics.report[fileName].mcCabeMetrics.metrics
            for objName in mccabe:
                objItem = [objName, str(mccabe[objName]), "M"]
                mccabeMetric = QTreeWidgetItem(objItem)
                mccabeItem.addChild(mccabeMetric)

            # COCOMO 2 part
            cocomo = [
                "COCOMO 2",
                str(metrics.report[fileName].cocomo2Metrics.value)
            ]
            cocomoItem = QTreeWidgetItem(cocomo)
            fileItem.addChild(cocomoItem)

        # Resizing the table
        self.__totalResultsTree.header().resizeSections(
            QHeaderView.ResizeToContents)

        # Add McCabe complexity information
        for fileName in metrics.report:
            mccabe = metrics.report[fileName].mcCabeMetrics.metrics
            for objName in mccabe:
                values = ["", fileName, objName, str(mccabe[objName])]
                self.__mcCabeTable.addTopLevelItem(McCabeTableItem(values))

        if not self.__shouldShowFileName(self.__mcCabeTable, 1):
            self.__mcCabeTable.setColumnHidden(1, True)

        # Resizing and sorting the table
        self.__mcCabeTable.header().setSortIndicator(3, Qt.DescendingOrder)
        self.__mcCabeTable.sortItems(
            3,
            self.__mcCabeTable.header().sortIndicatorOrder())
        self.__mcCabeTable.header().resizeSections(
            QHeaderView.ResizeToContents)

        # Show the complete information
        self.__mcCabeTable.hide()
        self.__totalResultsTree.show()

        self.__reportShown = True
        self.__updateButtonsStatus()
        self.__updateTooltip()

        # It helps, but why do I have flickering?
        QApplication.processEvents()
        return

    def __accumulateBasicMetrics(self):
        " Accumulates basic metrics for all the processed files "
        basic = {}
        for fileName in self.__report.report:
            singleBasic = self.__report.report[fileName].basicMetrics.metrics
            for key in singleBasic:
                if not key.startswith('num'):
                    continue
                if key in basic:
                    basic[key] += int(singleBasic[key])
                else:
                    basic[key] = int(singleBasic[key])
        return basic

    def __mcCabeActivated(self, item, column):
        " Handles the double click (or Enter) on the mccabe table item "

        objName = str(item.text(2))
        if self.__reportOption == self.SingleBuffer:
            if os.path.isabs(self.__reportFileName):
                fileName = self.__reportFileName
            else:
                fileName = ""
        else:
            fileName = str(item.text(1))
        self.__onMcCabeObject(objName, fileName)
        return

    def __allItemActivated(self, item, column):
        " Handles the double click (or Enter) in the total results tree "

        # We process only the error messages and McCabe items
        hiddenColumnText = str(item.text(2))
        if not hiddenColumnText in ["M", "E"]:
            return

        fileName = self.__getTreeItemFileName(item)
        lineNumber = 0
        if hiddenColumnText == "M":
            # This is McCabe item
            objName = str(item.text(0))
            self.__onMcCabeObject(objName, fileName)
            return
        elif hiddenColumnText == "E":
            # This is an error message
            message = str(item.text(0))
            pos = message.find("at line")
            if pos == -1:
                logging.error("Unknown format of the message. "
                              "Please inform the developers.")
                return
            parts = message[pos:].split()
            try:
                lineNumber = int(parts[2].replace(',', ''))
            except:
                logging.error("Unknown format of the message. "
                              "Please inform the developers.")
                return

            if fileName == "":
                # This is an unsaved buffer, try to find the editor by UUID
                mainWindow = GlobalData().mainWindow
                widget = mainWindow.getWidgetByUUID(self.__reportUUID)
                if widget is None:
                    logging.error("The unsaved buffer has been closed")
                    return
                # The widget was found, so jump to the required
                editor = widget.getEditor()
                editor.gotoLine(lineNumber)
                editor.setFocus()
                return

        GlobalData().mainWindow.openFile(fileName, lineNumber)
        return

    def __getTreeItemFileName(self, item):
        " Identifies the tree view item file name "
        if self.__reportOption == self.SingleBuffer:
            if os.path.isabs(self.__reportFileName):
                return self.__reportFileName
            return ""

        # The file name is always two levels up
        fileItem = item.parent().parent()
        return str(fileItem.text(0))

    def __onMcCabeObject(self, objName, fileName):
        " Called when the user activated McCabe item "

        info = None

        mainWindow = GlobalData().mainWindow
        widget = mainWindow.getWidgetByUUID(self.__reportUUID)
        if widget is None:
            if fileName == "":
                logging.error("The unsaved buffer has been closed")
                return
            # No widget, but we know the file name
            info = getBriefModuleInfoFromFile(fileName)
        else:
            # The widget was found
            editor = widget.getEditor()
            # The editor content has been modified, so re-parse the buffer
            info = getBriefModuleInfoFromMemory(editor.text())

        parts = objName.split('.')
        currentIndex = 0
        functionsContainer = info.functions
        classesContainer = info.classes
        line = -1

        if objName == "__main__" and len(parts) == 1:
            # Special case - global file scope
            line = 1
            currentIndex = 1

        while currentIndex < len(parts):
            found = False
            for func in functionsContainer:
                if func.name == parts[currentIndex]:
                    if currentIndex == len(parts) - 1:
                        # Found, jump to the line
                        line = func.line
                        break
                    functionsContainer = func.functions
                    classesContainer = func.classes
                    found = True
                    break
            if line != -1:
                break
            if found:
                currentIndex += 1
                continue
            for klass in classesContainer:
                if klass.name == parts[currentIndex]:
                    if currentIndex == len(parts) - 1:
                        # Found, jump to the line
                        line = klass.line
                        break
                    functionsContainer = klass.functions
                    classesContainer = klass.classes
                    found = True
            if line != -1:
                break
            if found:
                currentIndex += 1
                continue

            # Not found
            logging.error("Cannot find the " + objName)
            return

        # Here we have the line number
        if widget is None:
            GlobalData().mainWindow.openFile(fileName, line)
        else:
            editor = widget.getEditor()
            editor.gotoLine(line)
            editor.setFocus()
        return

    def onFileUpdated(self, fileName, uuid):
        " Called when a buffer is saved or saved as "

        if not self.__reportShown:
            return
        if self.__reportUUID != uuid:
            return

        # Currently shown report is for the saved buffer
        # File name is expected being absolute
        self.__reportFileName = fileName
        self.emit(SIGNAL('updatePymetricsTooltip'),
                  "Metrics generated for buffer saved as " + fileName)
        return
예제 #14
0
class FindInFilesViewer(QWidget):
    " Find in files viewer tab widget "

    lastEntered = None

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

        global searchTooltip
        searchTooltip = Tooltip()

        self.__reportRegexp = None
        self.__reportResults = []
        self.__reportShown = False
        self.__bufferChangeconnected = False

        # Prepare members for reuse
        self.__noneLabel = QLabel("\nNo results available")

        self.__noneLabel.setFrameShape(QFrame.StyledPanel)
        self.__noneLabel.setAlignment(Qt.AlignHCenter)
        self.__headerFont = self.__noneLabel.font()
        self.__headerFont.setPointSize(self.__headerFont.pointSize() + 4)
        self.__noneLabel.setFont(self.__headerFont)
        self.__noneLabel.setAutoFillBackground(True)
        noneLabelPalette = self.__noneLabel.palette()
        noneLabelPalette.setColor(QPalette.Background,
                                  GlobalData().skin.nolexerPaper)
        self.__noneLabel.setPalette(noneLabelPalette)

        # Keep pylint happy
        self.printButton = None
        self.clearButton = None
        self.printPreviewButton = None

        self.__createLayout(parent)

        self.__updateButtonsStatus()

        GlobalData().project.projectChanged.connect(self.__onProjectChanged)
        return

    def __createLayout(self, parent):
        " Creates the toolbar and layout "

        # Buttons
        self.printButton = QAction(PixmapCache().getIcon('printer.png'),
                                   'Print', self)
        #printButton.setShortcut( 'Ctrl+' )
        self.printButton.triggered.connect(self.__onPrint)
        self.printButton.setVisible(False)

        self.printPreviewButton = QAction(
            PixmapCache().getIcon('printpreview.png'), 'Print preview', self)
        #printPreviewButton.setShortcut( 'Ctrl+' )
        self.printPreviewButton.triggered.connect(self.__onPrintPreview)
        self.printPreviewButton.setVisible(False)

        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.clearButton = QAction(PixmapCache().getIcon('trash.png'), 'Clear',
                                   self)
        self.clearButton.triggered.connect(self.__clear)

        # The toolbar
        self.toolbar = QToolBar(self)
        self.toolbar.setOrientation(Qt.Vertical)
        self.toolbar.setMovable(False)
        self.toolbar.setAllowedAreas(Qt.RightToolBarArea)
        self.toolbar.setIconSize(QSize(16, 16))
        self.toolbar.setFixedWidth(28)
        self.toolbar.setContentsMargins(0, 0, 0, 0)

        self.toolbar.addAction(self.printPreviewButton)
        self.toolbar.addAction(self.printButton)
        self.toolbar.addWidget(spacer)
        self.toolbar.addAction(self.clearButton)

        self.__resultsTree = FindResultsTreeWidget()
        self.__resultsTree.setAlternatingRowColors(True)
        self.__resultsTree.setRootIsDecorated(True)
        self.__resultsTree.setItemsExpandable(True)
        self.__resultsTree.setUniformRowHeights(True)
        self.__resultsTree.setItemDelegate(NoOutlineHeightDelegate(4))
        headerLabels = ["File name / line", "Text"]
        self.__resultsTree.setHeaderLabels(headerLabels)
        self.__resultsTree.itemActivated.connect(self.__resultActivated)
        self.__resultsTree.itemClicked.connect(self.__resultClicked)
        self.__resultsTree.setMouseTracking(True)
        self.__resultsTree.itemEntered.connect(self.__itemEntered)
        self.__resultsTree.hide()

        self.__hLayout = QHBoxLayout()
        self.__hLayout.setContentsMargins(0, 0, 0, 0)
        self.__hLayout.setSpacing(0)
        self.__hLayout.addWidget(self.toolbar)
        self.__hLayout.addWidget(self.__noneLabel)
        self.__hLayout.addWidget(self.__resultsTree)

        self.setLayout(self.__hLayout)
        return

    def getResultsTree(self):
        " Provides a reference to the results tree "
        return self.__resultsTree

    def __updateButtonsStatus(self):
        " Updates the buttons status "
        self.printButton.setEnabled(self.__reportShown)
        self.printPreviewButton.setEnabled(self.__reportShown)
        self.clearButton.setEnabled(self.__reportShown)
        return

    def __onPrint(self):
        " Triggered when the print button is pressed "
        pass

    def __onPrintPreview(self):
        " triggered when the print preview button is pressed "
        pass

    def setFocus(self):
        " Overridden setFocus "
        self.__hLayout.setFocus()
        return

    def __onProjectChanged(self, what):
        " Triggered when a project is changed "
        if what == CodimensionProject.CompleteProject:
            self.__clear()
        return

    def __clear(self):
        " Clears the content of the vertical layout "
        if not self.__reportShown:
            return

        # Disconnect the buffer change signal if it is connected
        if self.__bufferChangeconnected:
            self.__bufferChangeconnected = False
            mainWindow = GlobalData().mainWindow
            editorsManager = mainWindow.editorsManagerWidget.editorsManager
            editorsManager.bufferModified.disconnect(
                self.__resultsTree.onBufferModified)

        self.__resultsTree.resetCache()
        self.__resultsTree.clear()
        self.__resultsTree.hide()
        self.__noneLabel.show()

        self.__reportRegexp = None
        self.__reportResults = []
        self.__reportShown = False
        self.__updateButtonsStatus()
        return

    def showReport(self, regexp, results):
        " Shows the find in files results "
        self.__clear()
        self.__noneLabel.hide()

        self.__reportRegexp = regexp
        self.__reportResults = results

        # Add the complete information
        totalMatched = 0
        for item in results:
            matched = len(item.matches)
            totalMatched += matched
            if matched == 1:
                matchText = " (1 match)"
            else:
                matchText = " (" + str(matched) + " matches)"
            columns = [item.fileName, matchText]
            fileItem = MatchTableFileItem(columns, item.bufferUUID)
            fileItem.setIcon(0, getFileIcon(detectFileType(item.fileName)))
            if item.tooltip != "":
                fileItem.setToolTip(0, item.tooltip)
            self.__resultsTree.addTopLevelItem(fileItem)

            # Matches
            for match in item.matches:
                columns = [str(match.line), match.text]
                matchItem = MatchTableItem(columns, match.tooltip)
                fileItem.addChild(matchItem)
            fileItem.setExpanded(True)

        # Update the header with the total number of matches
        headerLabels = [
            "File name / line (total files: " + str(len(results)) + ")",
            "Text (total matches: " + str(totalMatched) + ")"
        ]
        self.__resultsTree.setHeaderLabels(headerLabels)

        # Resizing the table
        self.__resultsTree.header().resizeSections(
            QHeaderView.ResizeToContents)

        # Show the complete information
        self.__resultsTree.show()
        self.__resultsTree.buildCache()

        self.__reportShown = True
        self.__updateButtonsStatus()

        # Connect the buffer change signal if not connected yet
        if not self.__bufferChangeconnected:
            self.__bufferChangeconnected = True
            mainWindow = GlobalData().mainWindow
            editorsManager = mainWindow.editorsManagerWidget.editorsManager
            editorsManager.bufferModified.connect(
                self.__resultsTree.onBufferModified)
        return

    def __resultClicked(self, item, column):
        " Handles the single click "
        hideSearchTooltip()
        return

    def __resultActivated(self, item, column):
        " Handles the double click (or Enter) on a match "
        if type(item) == MatchTableItem:
            fileName = str(item.parent().data(0, Qt.DisplayRole).toString())
            lineNumber = int(item.data(0, Qt.DisplayRole).toString())
            GlobalData().mainWindow.openFile(fileName, lineNumber)
            hideSearchTooltip()
            return

    def __itemEntered(self, item, column):
        " Triggered when the mouse cursor entered a row "

        if type(item) != MatchTableItem:
            self.lastEntered = item
            hideSearchTooltip()
            return

        if column != 1:
            # Show the tooltip only for the column with results
            self.lastEntered = None
            hideSearchTooltip()
            return

        # Memorize the row height for proper tooltip displaying later
        global cellHeight
        cellHeight = self.__resultsTree.visualItemRect(item).height()

        if self.lastEntered != item or not inside:
            item.itemEntered()
            self.lastEntered = item
        return
예제 #15
0
    def __createLayout(self, scriptName, name, code, reportTime):
        " Creates the toolbar and layout "

        # Buttons
        self.__printButton = QAction(PixmapCache().getIcon('printer.png'),
                                     'Print', self)
        self.__printButton.triggered.connect(self.__onPrint)
        self.__printButton.setEnabled(False)
        self.__printButton.setVisible(False)

        self.__printPreviewButton = QAction(
            PixmapCache().getIcon('printpreview.png'), 'Print preview', self)
        self.__printPreviewButton.triggered.connect(self.__onPrintPreview)
        self.__printPreviewButton.setEnabled(False)
        self.__printPreviewButton.setVisible(False)

        # Zoom buttons
        self.__zoomInButton = QAction(PixmapCache().getIcon('zoomin.png'),
                                      'Zoom in (Ctrl+=)', self)
        self.__zoomInButton.triggered.connect(self.onZoomIn)

        self.__zoomOutButton = QAction(PixmapCache().getIcon('zoomout.png'),
                                       'Zoom out (Ctrl+-)', self)
        self.__zoomOutButton.triggered.connect(self.onZoomOut)

        self.__zoomResetButton = QAction(
            PixmapCache().getIcon('zoomreset.png'), 'Zoom reset (Ctrl+0)',
            self)
        self.__zoomResetButton.triggered.connect(self.onZoomReset)

        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        # Toolbar
        toolbar = QToolBar(self)
        toolbar.setOrientation(Qt.Vertical)
        toolbar.setMovable(False)
        toolbar.setAllowedAreas(Qt.RightToolBarArea)
        toolbar.setIconSize(QSize(16, 16))
        toolbar.setFixedWidth(28)
        toolbar.setContentsMargins(0, 0, 0, 0)

        toolbar.addAction(self.__printPreviewButton)
        toolbar.addAction(self.__printButton)
        toolbar.addWidget(spacer)
        toolbar.addAction(self.__zoomInButton)
        toolbar.addAction(self.__zoomOutButton)
        toolbar.addAction(self.__zoomResetButton)

        summary = QLabel("<b>Script:</b> " + scriptName + "<br>"
                         "<b>Name:</b> " + name + "<br>"
                         "<b>Disassembled at:</b> " + reportTime)
        summary.setFrameStyle(QFrame.StyledPanel)
        summary.setAutoFillBackground(True)
        summaryPalette = summary.palette()
        summaryBackground = summaryPalette.color(QPalette.Background)
        summaryBackground.setRgb(min(summaryBackground.red() + 30, 255),
                                 min(summaryBackground.green() + 30, 255),
                                 min(summaryBackground.blue() + 30, 255))
        summaryPalette.setColor(QPalette.Background, summaryBackground)
        summary.setPalette(summaryPalette)

        self.__text = DisasmWidget(self)
        self.__text.setAcceptRichText(False)
        self.__text.setLineWrapMode(QTextEdit.NoWrap)
        self.__text.setFont(GlobalData().skin.nolexerFont)
        self.zoomTo(Settings().zoom)
        self.__text.setReadOnly(True)
        self.__text.setPlainText(code)

        vLayout = QVBoxLayout()
        vLayout.addWidget(summary)
        vLayout.addWidget(self.__text)

        hLayout = QHBoxLayout()
        hLayout.setContentsMargins(0, 0, 0, 0)
        hLayout.setSpacing(0)
        hLayout.addLayout(vLayout)
        hLayout.addWidget(toolbar)

        self.setLayout(hLayout)
        return
예제 #16
0
class Tooltip(QFrame):
    " Custom tooltip "

    def __init__(self):
        QFrame.__init__(self)

        # Avoid the border around the window
        self.setWindowFlags(Qt.SplashScreen)

        # Make the frame nice looking
        self.setFrameShape(QFrame.StyledPanel)
        self.setLineWidth(2)

        self.info = None
        self.location = None
        self.__createLayout()

        # The item the tooltip is for
        self.item = None

        # The timer which shows the tooltip. The timer is controlled from
        # outside of the class.
        self.tooltipTimer = QTimer(self)
        self.tooltipTimer.setSingleShot(True)
        self.tooltipTimer.timeout.connect(self.__onTimer)

        self.startPosition = None
        return

    def __createLayout(self):
        " Creates the tooltip layout "
        verticalLayout = QVBoxLayout(self)
        self.info = QLabel()
        self.info.setAutoFillBackground(True)
        font = self.info.font()
        font.setFamily(GlobalData().skin.baseMonoFontFace)
        self.info.setFont(font)
        self.info.setFrameShape(QFrame.StyledPanel)
        verticalLayout.addWidget(self.info)
        verticalLayout.setMargin(0)
        self.location = QLabel()
        verticalLayout.addWidget(self.location)
        return

    def setText(self, text):
        " Sets the tooltip text "
        self.info.setText(text)
        return

    def setLocation(self, text):
        " Sets the file name and line at the bottom "
        self.location.setText(text)
        return

    def setModified(self, status):
        " Sets the required tooltip background "
        palette = self.info.palette()
        if status:
            # Reddish
            palette.setColor(QPalette.Background, QColor(255, 227, 227))
        else:
            # Blueish
            palette.setColor(QPalette.Background, QColor(224, 236, 255))
        self.info.setPalette(palette)
        return

    def setItem(self, item):
        " Sets the item the tooltip is shown for "
        self.item = item
        return

    def __getTooltipPos(self):
        " Calculates the tooltip position - above the row "
        pos = QCursor.pos()
        if pos.x() + self.sizeHint().width() >= screenWidth:
            pos.setX(screenWidth - self.sizeHint().width() - 2)
        pos.setY(pos.y() - cellHeight - 1 - self.sizeHint().height())
        return pos

    def __onTimer(self):
        " Triggered by the show tooltip timer "
        currentPos = QCursor.pos()
        if abs(currentPos.x() - self.startPosition.x()) <= 2 and abs(currentPos.y() - self.startPosition.y()) <= 2:
            # No movement since last time, show the tooltip
            self.show()
            return

        # There item has not been changed, but the position within it was
        # So restart the timer, but for shorter
        self.startPosition = currentPos
        self.tooltipTimer.start(400)
        return

    def startShowTimer(self):
        " Memorizes the cursor position and starts the timer "
        self.tooltipTimer.stop()
        self.startPosition = QCursor.pos()
        self.tooltipTimer.start(500)  # 0.5 sec
        return

    def show(self):
        " Shows the tooltip at the proper position "
        QToolTip.hideText()
        QApplication.processEvents()
        if not inside:
            return
        self.move(self.__getTooltipPos())
        self.raise_()
        QFrame.show(self)
        return
예제 #17
0
class FindInFilesViewer(QWidget):
    " Find in files viewer tab widget "

    lastEntered = None

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

        global searchTooltip
        searchTooltip = Tooltip()

        self.__reportRegexp = None
        self.__reportResults = []
        self.__reportShown = False
        self.__bufferChangeconnected = False

        # Prepare members for reuse
        self.__noneLabel = QLabel("\nNo results available")

        self.__noneLabel.setFrameShape(QFrame.StyledPanel)
        self.__noneLabel.setAlignment(Qt.AlignHCenter)
        self.__headerFont = self.__noneLabel.font()
        self.__headerFont.setPointSize(self.__headerFont.pointSize() + 4)
        self.__noneLabel.setFont(self.__headerFont)
        self.__noneLabel.setAutoFillBackground(True)
        noneLabelPalette = self.__noneLabel.palette()
        noneLabelPalette.setColor(QPalette.Background, GlobalData().skin.nolexerPaper)
        self.__noneLabel.setPalette(noneLabelPalette)

        # Keep pylint happy
        self.printButton = None
        self.clearButton = None
        self.printPreviewButton = None

        self.__createLayout(parent)

        self.__updateButtonsStatus()

        GlobalData().project.projectChanged.connect(self.__onProjectChanged)
        return

    def __createLayout(self, parent):
        " Creates the toolbar and layout "

        # Buttons
        self.printButton = QAction(PixmapCache().getIcon("printer.png"), "Print", self)
        # printButton.setShortcut( 'Ctrl+' )
        self.printButton.triggered.connect(self.__onPrint)
        self.printButton.setVisible(False)

        self.printPreviewButton = QAction(PixmapCache().getIcon("printpreview.png"), "Print preview", self)
        # printPreviewButton.setShortcut( 'Ctrl+' )
        self.printPreviewButton.triggered.connect(self.__onPrintPreview)
        self.printPreviewButton.setVisible(False)

        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.clearButton = QAction(PixmapCache().getIcon("trash.png"), "Clear", self)
        self.clearButton.triggered.connect(self.__clear)

        # The toolbar
        self.toolbar = QToolBar(self)
        self.toolbar.setOrientation(Qt.Vertical)
        self.toolbar.setMovable(False)
        self.toolbar.setAllowedAreas(Qt.RightToolBarArea)
        self.toolbar.setIconSize(QSize(16, 16))
        self.toolbar.setFixedWidth(28)
        self.toolbar.setContentsMargins(0, 0, 0, 0)

        self.toolbar.addAction(self.printPreviewButton)
        self.toolbar.addAction(self.printButton)
        self.toolbar.addWidget(spacer)
        self.toolbar.addAction(self.clearButton)

        self.__resultsTree = FindResultsTreeWidget()
        self.__resultsTree.setAlternatingRowColors(True)
        self.__resultsTree.setRootIsDecorated(True)
        self.__resultsTree.setItemsExpandable(True)
        self.__resultsTree.setUniformRowHeights(True)
        self.__resultsTree.setItemDelegate(NoOutlineHeightDelegate(4))
        headerLabels = ["File name / line", "Text"]
        self.__resultsTree.setHeaderLabels(headerLabels)
        self.__resultsTree.itemActivated.connect(self.__resultActivated)
        self.__resultsTree.itemClicked.connect(self.__resultClicked)
        self.__resultsTree.setMouseTracking(True)
        self.__resultsTree.itemEntered.connect(self.__itemEntered)
        self.__resultsTree.hide()

        self.__hLayout = QHBoxLayout()
        self.__hLayout.setContentsMargins(0, 0, 0, 0)
        self.__hLayout.setSpacing(0)
        self.__hLayout.addWidget(self.toolbar)
        self.__hLayout.addWidget(self.__noneLabel)
        self.__hLayout.addWidget(self.__resultsTree)

        self.setLayout(self.__hLayout)
        return

    def getResultsTree(self):
        " Provides a reference to the results tree "
        return self.__resultsTree

    def __updateButtonsStatus(self):
        " Updates the buttons status "
        self.printButton.setEnabled(self.__reportShown)
        self.printPreviewButton.setEnabled(self.__reportShown)
        self.clearButton.setEnabled(self.__reportShown)
        return

    def __onPrint(self):
        " Triggered when the print button is pressed "
        pass

    def __onPrintPreview(self):
        " triggered when the print preview button is pressed "
        pass

    def setFocus(self):
        " Overridden setFocus "
        self.__hLayout.setFocus()
        return

    def __onProjectChanged(self, what):
        " Triggered when a project is changed "
        if what == CodimensionProject.CompleteProject:
            self.__clear()
        return

    def __clear(self):
        " Clears the content of the vertical layout "
        if not self.__reportShown:
            return

        # Disconnect the buffer change signal if it is connected
        if self.__bufferChangeconnected:
            self.__bufferChangeconnected = False
            mainWindow = GlobalData().mainWindow
            editorsManager = mainWindow.editorsManagerWidget.editorsManager
            editorsManager.bufferModified.disconnect(self.__resultsTree.onBufferModified)

        self.__resultsTree.resetCache()
        self.__resultsTree.clear()
        self.__resultsTree.hide()
        self.__noneLabel.show()

        self.__reportRegexp = None
        self.__reportResults = []
        self.__reportShown = False
        self.__updateButtonsStatus()
        return

    def showReport(self, regexp, results):
        " Shows the find in files results "
        self.__clear()
        self.__noneLabel.hide()

        self.__reportRegexp = regexp
        self.__reportResults = results

        # Add the complete information
        totalMatched = 0
        for item in results:
            matched = len(item.matches)
            totalMatched += matched
            if matched == 1:
                matchText = " (1 match)"
            else:
                matchText = " (" + str(matched) + " matches)"
            columns = [item.fileName, matchText]
            fileItem = MatchTableFileItem(columns, item.bufferUUID)
            fileItem.setIcon(0, getFileIcon(detectFileType(item.fileName)))
            if item.tooltip != "":
                fileItem.setToolTip(0, item.tooltip)
            self.__resultsTree.addTopLevelItem(fileItem)

            # Matches
            for match in item.matches:
                columns = [str(match.line), match.text]
                matchItem = MatchTableItem(columns, match.tooltip)
                fileItem.addChild(matchItem)
            fileItem.setExpanded(True)

        # Update the header with the total number of matches
        headerLabels = [
            "File name / line (total files: " + str(len(results)) + ")",
            "Text (total matches: " + str(totalMatched) + ")",
        ]
        self.__resultsTree.setHeaderLabels(headerLabels)

        # Resizing the table
        self.__resultsTree.header().resizeSections(QHeaderView.ResizeToContents)

        # Show the complete information
        self.__resultsTree.show()
        self.__resultsTree.buildCache()

        self.__reportShown = True
        self.__updateButtonsStatus()

        # Connect the buffer change signal if not connected yet
        if not self.__bufferChangeconnected:
            self.__bufferChangeconnected = True
            mainWindow = GlobalData().mainWindow
            editorsManager = mainWindow.editorsManagerWidget.editorsManager
            editorsManager.bufferModified.connect(self.__resultsTree.onBufferModified)
        return

    def __resultClicked(self, item, column):
        " Handles the single click "
        hideSearchTooltip()
        return

    def __resultActivated(self, item, column):
        " Handles the double click (or Enter) on a match "
        if type(item) == MatchTableItem:
            fileName = str(item.parent().data(0, Qt.DisplayRole).toString())
            lineNumber = int(item.data(0, Qt.DisplayRole).toString())
            GlobalData().mainWindow.openFile(fileName, lineNumber)
            hideSearchTooltip()
            return

    def __itemEntered(self, item, column):
        " Triggered when the mouse cursor entered a row "

        if type(item) != MatchTableItem:
            self.lastEntered = item
            hideSearchTooltip()
            return

        if column != 1:
            # Show the tooltip only for the column with results
            self.lastEntered = None
            hideSearchTooltip()
            return

        # Memorize the row height for proper tooltip displaying later
        global cellHeight
        cellHeight = self.__resultsTree.visualItemRect(item).height()

        if self.lastEntered != item or not inside:
            item.itemEntered()
            self.lastEntered = item
        return
예제 #18
0
    def create_locks_tab(self):
        self.specify_by_currency = QComboBox()

        def on_change_currency(currency):
            if currency != self.Locks_currency:
                self.Locks_currency = LOCKS_CURRENCIES[currency]
            self.specify_by_currency.clear()
            otheri = 0 if self.specify_by_currency.findText('BTC') > 0 else 1
            self.specify_by_currency.removeItem(otheri)
            self.specify_by_currency.addItem(str(LOCKS_CURRENCIES[currency]))
            self.specify_by_currency.addItem('BTC')
            self.specify_by_currency.setMaximumWidth(60)

        def on_btc_amount_change(amount):
            if amount != self.Locks_amount:
                self.Locks_amount = amount

        def on_change_action(act):
            action = LOCK_ACTIONS[act]
            if action != self.Locks_action:
                self.Locks_action = action

        def get_quote():
            specifiedCurrency = self.specify_by_currency.currentText()
            def get_lock():
                if specifiedCurrency == 'BTC':
                    amount = float(self.Locks_amount)
                    outAmount = 0
                else:
                    amount = 0
                    outAmount = float(self.Locks_amount)
                try:
                    lock = self.client.lock(amount=amount, outAmount=outAmount, currency=self.Locks_currency)
                    # print json.dumps(lock, indent=4)
                    pending_locks = self.config.get('pending_locks', [])
                    pending_locks.append(lock)
                    self.config.set_key('pending_locks', pending_locks, True)
                    return lock
                except (CoinapultError, CoinapultErrorECC) as ce:
                    QMessageBox.warning(None, _('Lock Failed'),
                                        _('Lock action failed due to reason: %s') % ce, _('OK'))

            def get_unlock():
                if specifiedCurrency == 'BTC':
                    amount = 0
                    outAmount = float(self.Locks_amount)
                else:
                    amount = float(self.Locks_amount)
                    outAmount = 0

                for addr in self.wallet.addresses():
                    u, used = self.wallet.is_used(addr)
                    if not used and u == 0:
                        self.unlock_address = addr
                        break
                try:
                    unlock = self.client.unlock(amount=amount, outAmount=outAmount,
                                                currency=str(self.Locks_currency),
                                                address=str(self.unlock_address))
                    # print json.dumps(unlock, indent=4)
                    pending_unlocks = self.config.get('pending_unlocks', [])
                    pending_unlocks.append(unlock)
                    self.config.set_key('pending_unlocks', pending_unlocks, True)
                    return unlock
                except (CoinapultError, CoinapultErrorECC) as ce:
                    QMessageBox.warning(None, _('Unlock Failed'),
                                        _('Unlock action failed due to reason: %s') % ce, _('OK'))

            self.quote_button.setDisabled(True)
            if self.Locks_action == 'Lock':
                self.waiting_dialog = WaitingDialog(w, 'Requesting Lock Quote',
                                                    get_lock, self.lock_confirm_dialog)
                self.waiting_dialog.start()
            else:
                self.waiting_dialog = WaitingDialog(w, 'Requesting Unlock Quote',
                                                    get_unlock, self.unlock_confirm_dialog)
                self.waiting_dialog.start()

        w = QWidget()
        self.tabLayout = QGridLayout(w)
        self.tabLayout.setColumnMinimumWidth(3, 400)
        self.tabLayout.setColumnStretch(0, 5)
        self.tabLayout.setHorizontalSpacing(10)

        about_locks_label = QLabel(ABOUT_LOCKS)
        about_locks_label.setWordWrap(True)
        about_locks_label.setOpenExternalLinks(True)
        self.tabLayout.addWidget(about_locks_label, 0, 2, 2, 3, Qt.AlignTop)

        self.balsLayout = QGridLayout(w)
        self.balsLayout.setColumnMinimumWidth(35, 400)
        self.balsLayout.setHorizontalSpacing(10)
        # self.balsLayout.setFrameStyle(QFrame.VLine)

        row = 0
        balw = QLabel(_("<font size='5' style='bold'>Current Locks Balances</font>"))
        # balw.setBackgroundRole(QPalette_ColorRole=QPalette_ColorRole)
        balw.setBackgroundRole(QPalette.Midlight)
        balw.setAutoFillBackground(True)
        balw.setMinimumWidth(250)
        self.balsLayout.addWidget(balw, row, 0)
        row += 1
        for cur in LOCKS_CURRENCIES:
            if cur == 'XAU':
                disp_cur = "Gold oz"
            elif cur == 'XAG':
                disp_cur = "Silver oz"
            else:
                disp_cur = cur
            curw = QLabel(_("<font size='5'>- %s</font>" % disp_cur))
            curw.setBackgroundRole(QPalette.Light)
            curw.setAutoFillBackground(True)
            curw.setMinimumWidth(250)
            self.balsLayout.addWidget(curw, row, 0)
            row += 1
        self.tabLayout.addLayout(self.balsLayout, 0, 0, 2, 3, Qt.AlignTop)

        # self.tabLayout.addWidget(QLabel(_('Estimated Total BTC Value')), row, 0)
        # self.tabLayout.addWidget(QLabel(_('- BTC')), row, 1)
        # row += 1

        self.tabLayout.addWidget(QLabel(_('What do you want to do?')), 2, 0, Qt.AlignBottom)
        # row += 1
        self.tabLayout.addWidget(QLabel(_('Which Locks asset?')), 2, 1, Qt.AlignBottom)
        # row += 1
        # row += 1

        self.tabLayout.addWidget(QLabel(_('Amount')), 2, 2, 1, 2, Qt.AlignBottom)
        # self.tabLayout.addWidget(QLabel(_('')), row, 0)
        # self.tabLayout.addWidget(QLabel(_('How much of which?')), 2, 3, Qt.AlignBottom)
        row += 1

        combo_action = QComboBox()
        combo_action.currentIndexChanged.connect(on_change_action)
        combo_action.addItems(LOCK_ACTIONS)
        combo_action.setMaximumWidth(100)
        self.tabLayout.addWidget(combo_action, 3, 0, Qt.AlignTop)

        combo_currency = QComboBox()
        combo_currency.currentIndexChanged.connect(on_change_currency)
        combo_currency.addItems(LOCKS_CURRENCIES)
        combo_currency.setMaximumWidth(60)
        self.tabLayout.addWidget(combo_currency, 3, 1, Qt.AlignTop)

        btc_amount_edit = QLineEdit('0')
        btc_amount_edit.textChanged.connect(on_btc_amount_change)
        btc_amount_edit.setMaximumWidth(100)
        self.tabLayout.addWidget(btc_amount_edit, 3, 2, Qt.AlignRight)

        # self.specify_by_currency.currentIndexChanged.connect(on_change_specify_currency)
        self.specify_by_currency.addItems([''])
        self.specify_by_currency.setMaximumWidth(60)
        self.tabLayout.addWidget(self.specify_by_currency, 3, 3, Qt.AlignLeft)
        # row += 1

        self.quote_button = QPushButton(_('Get Quote'))
        self.quote_button.clicked.connect(get_quote)
        self.quote_button.setMaximumWidth(100)
        self.tabLayout.addWidget(self.quote_button, 5, 0, Qt.AlignBottom)
        return w
예제 #19
0
class PymetricsViewer( QWidget ):
    " Pymetrics tab widget "

    # Limits to colorize the McCabe score
    LittleRiskLimit = 10
    ModerateRiskLimit = 20
    HighRiskLimit = 50

    # Options of providing a report
    SingleFile     = 0
    DirectoryFiles = 1
    ProjectFiles   = 2
    SingleBuffer   = 3

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

        self.__reportUUID = ""
        self.__reportFileName = ""
        self.__reportOption = -1
        self.__reportShown = False
        self.__report = None

        # Prepare members for reuse
        self.__noneLabel = QLabel( "\nNo results available" )

        self.__noneLabel.setFrameShape( QFrame.StyledPanel )
        self.__noneLabel.setAlignment( Qt.AlignHCenter )
        self.__headerFont = self.__noneLabel.font()
        self.__headerFont.setPointSize( self.__headerFont.pointSize() + 4 )
        self.__noneLabel.setFont( self.__headerFont )
        self.__noneLabel.setAutoFillBackground( True )
        noneLabelPalette = self.__noneLabel.palette()
        noneLabelPalette.setColor( QPalette.Background,
                                   GlobalData().skin.nolexerPaper )
        self.__noneLabel.setPalette( noneLabelPalette )

        self.__createLayout( parent )

        self.__updateButtonsStatus()
        return

    def __createLayout( self, parent ):
        " Creates the toolbar and layout "

        # Buttons
        self.__mcCabeButton = QAction( PixmapCache().getIcon( 'tableview.png' ),
                                       'Switch to McCabe only table view',
                                       self )
        self.__mcCabeButton.setCheckable( True )
        self.connect( self.__mcCabeButton, SIGNAL( 'toggled(bool)' ),
                      self.__onMcCabe )

        self.printButton = QAction( PixmapCache().getIcon( 'printer.png' ),
                                    'Print', self )
        #printButton.setShortcut( 'Ctrl+' )
        self.connect( self.printButton, SIGNAL( 'triggered()' ),
                      self.__onPrint )
        self.printButton.setVisible( False )

        self.printPreviewButton = QAction(
                PixmapCache().getIcon( 'printpreview.png' ),
                'Print preview', self )
        #printPreviewButton.setShortcut( 'Ctrl+' )
        self.connect( self.printPreviewButton, SIGNAL( 'triggered()' ),
                      self.__onPrintPreview )
        self.printPreviewButton.setVisible( False )

        spacer = QWidget()
        spacer.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Expanding )

        self.clearButton = QAction(
            PixmapCache().getIcon( 'trash.png' ),
            'Clear', self )
        self.connect( self.clearButton, SIGNAL( 'triggered()' ),
                      self.__clear )

        # The toolbar
        self.toolbar = QToolBar( self )
        self.toolbar.setOrientation( Qt.Vertical )
        self.toolbar.setMovable( False )
        self.toolbar.setAllowedAreas( Qt.RightToolBarArea )
        self.toolbar.setIconSize( QSize( 16, 16 ) )
        self.toolbar.setFixedWidth( 28 )
        self.toolbar.setContentsMargins( 0, 0, 0, 0 )

        self.toolbar.addAction( self.__mcCabeButton )
        self.toolbar.addAction( self.printPreviewButton )
        self.toolbar.addAction( self.printButton )
        self.toolbar.addWidget( spacer )
        self.toolbar.addAction( self.clearButton )

        self.__totalResultsTree = QTreeWidget()
        self.__totalResultsTree.setAlternatingRowColors( True )
        self.__totalResultsTree.setRootIsDecorated( True )
        self.__totalResultsTree.setItemsExpandable( True )
        self.__totalResultsTree.setUniformRowHeights( True )
        self.__totalResultsTree.setItemDelegate( NoOutlineHeightDelegate( 4 ) )
        headerLabels = [ "Path / name", "Value", "" ]
        self.__totalResultsTree.setHeaderLabels( headerLabels )
        self.connect( self.__totalResultsTree,
                      SIGNAL( "itemActivated(QTreeWidgetItem *, int)" ),
                      self.__allItemActivated )
        self.connect( self.__totalResultsTree,
                      SIGNAL( "itemExpanded(QTreeWidgetItem *)" ),
                      self.__onResultsExpanded )
        self.__totalResultsTree.setColumnHidden( 2, True )
        self.__totalResultsTree.hide()

        self.__mcCabeTable = QTreeWidget()
        self.__mcCabeTable.setAlternatingRowColors( True )
        self.__mcCabeTable.setRootIsDecorated( False )
        self.__mcCabeTable.setItemsExpandable( False )
        self.__mcCabeTable.setSortingEnabled( True )
        self.__mcCabeTable.setItemDelegate( NoOutlineHeightDelegate( 4 ) )
        self.__mcCabeTable.setUniformRowHeights( True )
        headerLabels = [ "", "File name", "Object", "McCabe Complexity" ]
        self.__mcCabeTable.setHeaderLabels( headerLabels )
        self.connect( self.__mcCabeTable,
                      SIGNAL( "itemActivated(QTreeWidgetItem *, int)" ),
                      self.__mcCabeActivated )
        self.__mcCabeTable.hide()

        self.__hLayout = QHBoxLayout()
        self.__hLayout.setContentsMargins( 0, 0, 0, 0 )
        self.__hLayout.setSpacing( 0 )
        self.__hLayout.addWidget( self.toolbar )
        self.__hLayout.addWidget( self.__noneLabel )
        self.__hLayout.addWidget( self.__totalResultsTree )
        self.__hLayout.addWidget( self.__mcCabeTable )

        self.setLayout( self.__hLayout )
        return

    def getTotalResultsWidget( self ):
        " Provides a reference to the total results widget "
        return self.__totalResultsTree

    def getMcCabeResultsWidget( self ):
        " Provides a reference to the McCabe results widget "
        return self.__mcCabeTable

    def __updateButtonsStatus( self ):
        " Updates the buttons status "
        self.__mcCabeButton.setEnabled( self.__reportShown )
        self.printButton.setEnabled( self.__reportShown )
        self.printPreviewButton.setEnabled( self.__reportShown )
        self.clearButton.setEnabled( self.__reportShown )
        return

    def __onResultsExpanded( self, item ):
        " An item has been expanded, so the column width should be adjusted "
        self.__totalResultsTree.header().resizeSections(
                                            QHeaderView.ResizeToContents )
        return

    def __onPrint( self ):
        " Triggered when the print button is pressed "
        pass

    def __onPrintPreview( self ):
        " triggered when the print preview button is pressed "
        pass

    def __onMcCabe( self, state ):
        " Triggered when the metrics view is switched "

        if not self.__reportShown:
            return

        if state:
            self.__totalResultsTree.hide()
            self.__mcCabeTable.show()
            self.__mcCabeButton.setIcon(
                            PixmapCache().getIcon( 'treeview.png' ) )
            self.__mcCabeButton.setToolTip( "Switch to complete "
                                            "results tree view" )
        else:
            self.__mcCabeTable.hide()
            self.__totalResultsTree.show()
            self.__mcCabeButton.setIcon(
                            PixmapCache().getIcon( 'tableview.png' ) )
            self.__mcCabeButton.setToolTip( "Switch to McCabe only table view" )
        return

    def setFocus( self ):
        " Overridden setFocus "
        self.__hLayout.setFocus()
        return

    def __clear( self ):
        " Clears the content of the vertical layout "
        if not self.__reportShown:
            return

        self.__totalResultsTree.clear()
        self.__totalResultsTree.hide()
        self.__mcCabeTable.clear()
        self.__mcCabeTable.hide()
        self.__noneLabel.show()

        self.__report = None
        self.__reportShown = False
        self.__updateButtonsStatus()
#        self.resizeEvent()
        self.__mcCabeButton.setIcon( PixmapCache().getIcon( 'tableview.png' ) )
        self.__mcCabeButton.setToolTip( "Switch to McCabe only table view" )
        self.__mcCabeButton.setChecked( False )

        self.__updateTooltip()
        return

    def __updateTooltip( self ):
        " Generates a signal with appropriate string message "
        if not self.__reportShown:
            tooltip = "No metrics available"
        elif self.__reportOption == self.DirectoryFiles:
            tooltip = "Metrics generated for directory: " + \
                      self.__reportFileName
        elif self.__reportOption == self.ProjectFiles:
            tooltip = "Metrics generated for the whole project"
        elif self.__reportOption == self.SingleFile:
            tooltip = "Metrics generated for file: " + self.__reportFileName
        elif self.__reportOption == self.SingleBuffer:
            tooltip = "Metrics generated for unsaved file: " + \
                      self.__reportFileName
        else:
            tooltip = ""
        self.emit( SIGNAL( 'updatePymetricsTooltip' ), tooltip )
        return

    @staticmethod
    def __shouldShowFileName( table, column ):
        " Checks if the file name is the same "

        size = table.topLevelItemCount()
        if size == 0:
            return False

        index = size - 1
        firstName = table.topLevelItem( index ).text( column )
        index -= 1
        while index >= 0:
            if table.topLevelItem( index ).text( column ) != firstName:
                return True
            index -= 1
        return False

    def showReport( self, metrics, reportOption, fileName, uuid ):
        " Shows the pymetrics results "
        self.__clear()
        self.__noneLabel.hide()

        self.__report = metrics
        self.__reportUUID = uuid
        self.__reportFileName = fileName
        self.__reportOption = reportOption

        if len( metrics.report ) > 1:
            accumulatedBasic = self.__accumulateBasicMetrics()
            accItem = QTreeWidgetItem( [ "Cumulative basic metrics" ] )
            self.__totalResultsTree.addTopLevelItem( accItem )
            for key in accumulatedBasic:
                bmItem = [ BasicMetrics.metricsOfInterest[ key ],
                           splitThousands( str( accumulatedBasic[ key ] ) ) ]
                basicMetric = QTreeWidgetItem( bmItem )
                accItem.addChild( basicMetric )

        # Add the complete information
        for fileName in metrics.report:
            if reportOption == self.SingleBuffer:
                fileItem = QTreeWidgetItem( [ "Editor buffer" ] )
            else:
                fileItem = QTreeWidgetItem( [ fileName ] )
                info = GlobalData().briefModinfoCache.get( fileName )
                if info.docstring is not None:
                    fileItem.setToolTip( 0, info.docstring.text )
                else:
                    fileItem.setToolTip( 0, "" )
            self.__totalResultsTree.addTopLevelItem( fileItem )

            # Messages part
            messages = metrics.report[ fileName ].messages
            if len( messages ) > 0:
                messagesItem = QTreeWidgetItem( [ "Messages" ] )
                fileItem.addChild( messagesItem )
                for message in messages:
                    mItem = [ message, "", "E" ]
                    messagesItem.addChild( QTreeWidgetItem( mItem ) )

            # Basic metrics part
            basicItem = QTreeWidgetItem( [ "Basic metrics" ] )
            fileItem.addChild( basicItem )
            basic = metrics.report[ fileName ].basicMetrics
            for key in basic.metrics:
                bmItem = [ BasicMetrics.metricsOfInterest[ key ],
                           str( basic.metrics[ key ] ) ]
                basicMetric = QTreeWidgetItem( bmItem )
                basicItem.addChild( basicMetric )

            # McCabe part
            mccabeItem = QTreeWidgetItem( [ "McCabe metrics" ] )
            fileItem.addChild( mccabeItem )
            mccabe = metrics.report[ fileName ].mcCabeMetrics.metrics
            for objName in mccabe:
                objItem = [ objName, str( mccabe[ objName ] ), "M" ]
                mccabeMetric = QTreeWidgetItem( objItem )
                mccabeItem.addChild( mccabeMetric )


            # COCOMO 2 part
            cocomo = [ "COCOMO 2", str( metrics.report[ fileName ].cocomo2Metrics.value ) ]
            cocomoItem = QTreeWidgetItem( cocomo )
            fileItem.addChild( cocomoItem )



        # Resizing the table
        self.__totalResultsTree.header().resizeSections(
                                            QHeaderView.ResizeToContents )


        # Add McCabe complexity information
        for fileName in metrics.report:
            mccabe = metrics.report[ fileName ].mcCabeMetrics.metrics
            for objName in mccabe:
                values = [ "", fileName, objName, str( mccabe[ objName ] ) ]
                self.__mcCabeTable.addTopLevelItem( McCabeTableItem( values ) )

        if not self.__shouldShowFileName( self.__mcCabeTable, 1 ):
            self.__mcCabeTable.setColumnHidden( 1, True )

        # Resizing and sorting the table
        self.__mcCabeTable.header().setSortIndicator( 3, Qt.DescendingOrder )
        self.__mcCabeTable.sortItems( 3,
                          self.__mcCabeTable.header().sortIndicatorOrder() )
        self.__mcCabeTable.header().resizeSections(
                          QHeaderView.ResizeToContents )

        # Show the complete information
        self.__mcCabeTable.hide()
        self.__totalResultsTree.show()

        self.__reportShown = True
        self.__updateButtonsStatus()
        self.__updateTooltip()

        # It helps, but why do I have flickering?
        QApplication.processEvents()
        return

    def __accumulateBasicMetrics( self ):
        " Accumulates basic metrics for all the processed files "
        basic = {}
        for fileName in self.__report.report:
            singleBasic = self.__report.report[ fileName ].basicMetrics.metrics
            for key in singleBasic:
                if not key.startswith( 'num' ):
                    continue
                if key in basic:
                    basic[ key ] += int( singleBasic[ key ] )
                else:
                    basic[ key ] = int( singleBasic[ key ] )
        return basic

    def __mcCabeActivated( self, item, column ):
        " Handles the double click (or Enter) on the mccabe table item "

        objName = str( item.text( 2 ) )
        if self.__reportOption == self.SingleBuffer:
            if os.path.isabs( self.__reportFileName ):
                fileName = self.__reportFileName
            else:
                fileName = ""
        else:
            fileName = str( item.text( 1 ) )
        self.__onMcCabeObject( objName, fileName )
        return

    def __allItemActivated( self, item, column ):
        " Handles the double click (or Enter) in the total results tree "

        # We process only the error messages and McCabe items
        hiddenColumnText = str( item.text( 2 ) )
        if not hiddenColumnText in [ "M", "E" ]:
            return

        fileName = self.__getTreeItemFileName( item )
        lineNumber = 0
        if hiddenColumnText == "M":
            # This is McCabe item
            objName = str( item.text( 0 ) )
            self.__onMcCabeObject( objName, fileName )
            return
        elif hiddenColumnText == "E":
            # This is an error message
            message = str( item.text( 0 ) )
            pos = message.find( "at line" )
            if pos == -1:
                logging.error( "Unknown format of the message. "
                               "Please inform the developers." )
                return
            parts = message[ pos: ].split()
            try:
                lineNumber = int( parts[ 2 ].replace( ',', '' ) )
            except:
                logging.error( "Unknown format of the message. "
                               "Please inform the developers." )
                return

            if fileName == "":
                # This is an unsaved buffer, try to find the editor by UUID
                mainWindow = GlobalData().mainWindow
                widget = mainWindow.getWidgetByUUID( self.__reportUUID )
                if widget is None:
                    logging.error( "The unsaved buffer has been closed" )
                    return
                # The widget was found, so jump to the required
                editor = widget.getEditor()
                editor.gotoLine( lineNumber )
                editor.setFocus()
                return

        GlobalData().mainWindow.openFile( fileName, lineNumber )
        return

    def __getTreeItemFileName( self, item ):
        " Identifies the tree view item file name "
        if self.__reportOption == self.SingleBuffer:
            if os.path.isabs( self.__reportFileName ):
                return self.__reportFileName
            return ""

        # The file name is always two levels up
        fileItem = item.parent().parent()
        return str( fileItem.text( 0 ) )

    def __onMcCabeObject( self, objName, fileName ):
        " Called when the user activated McCabe item "

        info = None

        mainWindow = GlobalData().mainWindow
        widget = mainWindow.getWidgetByUUID( self.__reportUUID )
        if widget is None:
            if fileName == "":
                logging.error( "The unsaved buffer has been closed" )
                return
            # No widget, but we know the file name
            info = getBriefModuleInfoFromFile( fileName )
        else:
            # The widget was found
            editor = widget.getEditor()
            # The editor content has been modified, so re-parse the buffer
            info = getBriefModuleInfoFromMemory( editor.text() )

        parts = objName.split( '.' )
        currentIndex = 0
        functionsContainer = info.functions
        classesContainer = info.classes
        line = -1

        if objName == "__main__" and len( parts ) == 1:
            # Special case - global file scope
            line = 1
            currentIndex = 1

        while currentIndex < len( parts ):
            found = False
            for func in functionsContainer:
                if func.name == parts[ currentIndex ]:
                    if currentIndex == len( parts ) - 1:
                        # Found, jump to the line
                        line = func.line
                        break
                    functionsContainer = func.functions
                    classesContainer = func.classes
                    found = True
                    break
            if line != -1:
                break
            if found:
                currentIndex += 1
                continue
            for klass in classesContainer:
                if klass.name == parts[ currentIndex ]:
                    if currentIndex == len( parts ) - 1:
                        # Found, jump to the line
                        line = klass.line
                        break
                    functionsContainer = klass.functions
                    classesContainer = klass.classes
                    found = True
            if line != -1:
                break
            if found:
                currentIndex += 1
                continue

            # Not found
            logging.error( "Cannot find the " + objName )
            return

        # Here we have the line number
        if widget is None:
            GlobalData().mainWindow.openFile( fileName, line )
        else:
            editor = widget.getEditor()
            editor.gotoLine( line )
            editor.setFocus()
        return

    def onFileUpdated( self, fileName, uuid ):
        " Called when a buffer is saved or saved as "

        if not self.__reportShown:
            return
        if self.__reportUUID != uuid:
            return

        # Currently shown report is for the saved buffer
        # File name is expected being absolute
        self.__reportFileName = fileName
        self.emit( SIGNAL( 'updatePymetricsTooltip' ),
                   "Metrics generated for buffer saved as " + fileName )
        return
예제 #20
0
class filexplorerPluginMain(plugin.Plugin):
    ' main class for plugin '
    def initialize(self, *args, **kwargs):
        ' class init '
        global CONFIG_DIR
        ec = ExplorerContainer()
        super(filexplorerPluginMain, self).initialize(*args, **kwargs)

        self.dock = QDockWidget()
        self.dock.setAllowedAreas(Qt.LeftDockWidgetArea |
                                  Qt.RightDockWidgetArea)
        self.dock.setFeatures(QDockWidget.DockWidgetFloatable |
                              QDockWidget.DockWidgetMovable)
        self.dock.setWindowTitle("fileXplorer")
        self.dock.setStyleSheet('QDockWidget::title { text-align: center; }')

        # search for the truth
        self.srch = QLineEdit()
        #self.srch.resize(self.srch.size().height(), self.dock.size().width())
        self.srch.setPlaceholderText(' Search for Python files Local or PyPI ')
        self.srch.returnPressed.connect(self.search)

        # Disk Usage Bar
        self.hdbar = QProgressBar()
        if sys.platform != 'win32':
            self.hdbar.setMaximum(statvfs(HOME).f_blocks *
                statvfs(HOME).f_frsize / 1024 / 1024 / 1024)
            self.hdbar.setValue(statvfs(HOME).f_bfree *
                statvfs(HOME).f_frsize / 1024 / 1024 / 1024)
        self.hdbar.setToolTip(str(self.hdbar.value()) + '% Total Disk Use ')
        #self.hdbar.setStyleSheet('''QProgressBar{background-color:
        #QLinearGradient(spread:pad,x1:0,y1:0,x2:1,y2:1,stop:0 rgba(255,0,0,99),
        #stop:1 rgba(9,255,9,200));color:#fff;border:none;border-radius:9px;}
        #QProgressBar::chunk{background-color:QLinearGradient(spread:pad,y1:0,
        #x1:0,y2:1,x2:0.27,stop:0 rgb(0,0,0),stop:1 rgb(9,99,255));padding:0;
        #border:none;border-radius:9px;height:9px;margin:1px;}''')

        self.model = QDirModel()
        self.fileView = QColumnView(self.dock)
        self.fileView.setAlternatingRowColors(True)
        # self.fileView.setFont(QFont(self.fileView.font().setBold(True)))
        self.fileView.setIconSize(QSize(32, 32))
        self.fileView.setModel(self.model)
        self.fileView.updatePreviewWidget.connect(self.runfile)

        self.sli = QSlider()
        self.sli.setRange(16, 128)
        self.sli.setValue(32)
        self.sli.setToolTip('Icon Size: 32 px. Move Slider to change.')
        self.sli.setOrientation(Qt.Horizontal)
        self.sli.valueChanged.connect(lambda: self.fileView.setIconSize(
            QSize(self.sli.value(), self.sli.value())))
        self.sli.sliderReleased.connect(lambda:
            self.sli.setToolTip('Icon Size: ' + str(self.sli.value())))

        class TransientWidget(QWidget):
            ' persistant widget thingy '
            def __init__(self, widget_list):
                ' init sub class '
                super(TransientWidget, self).__init__()
                vbox = QVBoxLayout(self)
                for each_widget in widget_list:
                    vbox.addWidget(each_widget)

        tw = TransientWidget((self.srch, self.dock, self.sli, self.hdbar))
        ec.addTab(tw, "fileXplorer")

        ####

        self.process = QProcess()
        self.process.finished.connect(self.processFinished)

        self.preview = QLabel(self.fileView)
        self.preview.setTextFormat(0)
        self.preview.setStyleSheet('QLabel{font-size:9px;}')
        self.preview.setAutoFillBackground(True)
        self.fileView.setPreviewWidget(self.preview)
        self.dock.setWidget(self.fileView)

        # take a shot
        self.pic = QAction(QIcon.fromTheme("camera-photo"), 'Screenshot', self)
        self.pic.triggered.connect(lambda: QPixmap.grabWindow(
            QApplication.desktop().winId()).save(QFileDialog.getSaveFileName(
            self.dock, " Save Screenshot As ... ", HOME, ';;(*.png)')))

        # copy time
        self.tim = QAction(QIcon.fromTheme("user-away"),
                           'Date and Time to Clipboard', self)
        self.tim.triggered.connect(lambda: QApplication.clipboard().setText(
            datetime.now().strftime(" %A %B %d-%m-%Y %H:%M:%S %p ")))

        # color chooser
        self.cl = QAction(QIcon.fromTheme("applications-graphics"),
                          'Color Chooser to Clipboard', self)
        self.cl.triggered.connect(lambda: QApplication.clipboard().setText(
            '{}'.format(QColorDialog.getColor().name())))

        # icon chooser
        self.icn = QAction(QIcon.fromTheme("insert-image"),
                          'Icon Chooser to Clipboard', self)
        self.icn.triggered.connect(self.iconChooser)

        # tool bar with actions
        QToolBar(self.dock).addActions((self.cl, self.icn, self.tim, self.pic))

        self.textBrowser = QTextBrowser(self.dock)
        self.textBrowser.setAutoFillBackground(True)
        self.textBrowser.setGeometry(self.dock.geometry())
        self.textBrowser.hide()

    def processFinished(self):
        ' print info of finished processes '
        print(" INFO: OK: QProcess finished . . . ")

    def search(self):
        ' function to search python files '
        # get search results of python filenames local or remote
        pypi_url = 'http://pypi.python.org/pypi'
        # pypi query
        pypi = xmlrpclib.ServerProxy(pypi_url, transport=ProxyTransport())
        try:
            pypi_query = pypi.search({'name': str(self.srch.text()).lower()})
            pypi_fls = list(set(['pypi.python.org/pypi/' + a['name'] +
                   ' | pip install ' + a['name'] for a in pypi_query]))
        except:
            pypi_fls = '<b> ERROR: Internet not available! ಠ_ಠ </b>'
        s_out = ('<br> <br> <br> <h3> Search Local Python files: </h3> <hr> ' +
        # Jedi list comprehension for LOCAL search
        str(["{}/{}".format(root, f) for root, f in list(itertools.chain(*
            [list(itertools.product([root], files))
            for root, dirs, files in walk(str(
            QFileDialog.getExistingDirectory(self.dock,
            'Open Directory to Search', path.expanduser("~"))))]))
            if f.endswith(('.py', '.pyw', '.pth')) and not f.startswith('.')
            and str(self.srch.text()).lower().strip() in f]
        ).replace(',', '<br>') + '<hr><h3> Search PyPI Python files: </h3>' +
        # wraped pypi query REMOTE search
        str(pypi_fls).replace(',', '<br>') + '<hr>Auto-Proxy:ON,DoNotTrack:ON')
        # print(s_out)
        try:
            call('notify-send fileXplorer Searching...', shell=True)
        except:
            pass
        self.srch.clear()
        self.textBrowser.setGeometry(self.dock.geometry())
        self.textBrowser.setHtml(s_out)
        self.textBrowser.show()
        tmr = QTimer(self.fileView)
        tmr.timeout.connect(self.textBrowser.hide)
        tmr.start(20000)

    def iconChooser(self):
        ' Choose a Icon and copy it to clipboard '
        #
        from .std_icon_naming import std_icon_naming as a
        #
        prv = QDialog(self.dock)
        prv.setWindowFlags(Qt.FramelessWindowHint)
        prv.setAutoFillBackground(True)
        prv.setGeometry(self.fileView.geometry())
        table = QTableWidget(prv)
        table.setColumnCount(1)
        table.setRowCount(len(a))
        table.verticalHeader().setVisible(True)
        table.horizontalHeader().setVisible(False)
        table.setShowGrid(True)
        table.setIconSize(QSize(128, 128))
        for index, icon in enumerate(a):
            item = QTableWidgetItem(QIcon.fromTheme(icon), '')
            # item.setData(Qt.UserRole, '')
            item.setToolTip(icon)
            table.setItem(index, 0, item)
        table.clicked.connect(lambda: QApplication.clipboard().setText(
          'QtGui.QIcon.fromTheme("{}")'.format(table.currentItem().toolTip())))
        table.doubleClicked.connect(prv.close)
        table.resizeColumnsToContents()
        table.resizeRowsToContents()
        QLabel('<h3> <br> 1 Click Copy, 2 Clicks Close </h3>', table)
        table.resize(prv.size())
        prv.exec_()

    def runfile(self, index):
        ' run the choosed file '
        s = str(file(self.model.filePath(index), 'r').read().strip())
        f = str(self.model.filePath(index))
        # ctime is NOT crossplatform,metadata change on *nix,creation on Window
        # http://docs.python.org/library/os.path.html#os.path.getctime
        m = ''.join((f, N, str(path.getsize(f) / 1024), ' Kilobytes', N,
            str(len(file(f, 'r').readlines())), ' Lines', N,
            str(len(s.replace(N, ''))), ' Characters', N,
            str(len([a for a in sub('[^a-zA-Z0-9 ]', '', s).split(' ')
                if a != ''])), ' Words', N,
            str(len([a for a in s if a in punctuation])), ' Punctuation', N,
            oct(stat(f).st_mode)[-3:], ' Permissions', N,
            time.ctime(path.getatime(f)), ' Accessed', N,
            time.ctime(path.getmtime(f)), ' Modified', N,
            'Owner: ', str(self.model.fileInfo(index).owner()), N,
            'Is Writable: ', str(self.model.fileInfo(index).isWritable()), N,
            'Is Executable: ', str(self.model.fileInfo(index).isExecutable()),
            N, 'Is Hidden: ', str(self.model.fileInfo(index).isHidden()), N,
            'Is SymLink: ', str(self.model.fileInfo(index).isSymLink()), N,
            'File Extension: ', str(self.model.fileInfo(index).suffix())
        ))
        #print(m)
        self.preview.setToolTip(m)
        self.preview.setText(s)
        self.preview.resize(self.preview.size().width(),
                            self.dock.size().height())
        self.process.start('xdg-open {}'.format(f))
        if not self.process.waitForStarted():
            print((" ERROR: Process {} Failed ! ".format(str(f))))
            return
예제 #21
0
파일: scj.py 프로젝트: Ptaah/SCJ
class SCJProgress(QHBoxLayout):
    def __init__(self, parent=None, file=None, format=None, createDir=False ):
        super(SCJProgress, self).__init__(parent)
        self.format = format
        self.filename = file
        self.createDir = createDir
        self.process = SCJ(self.filename, self.format, createDir)
        self.output = QString(self.process.output)
        self.command = QStringList(self.process.command)
        self.log = QStringList()

        self.label = QLabel(self.output)
        self.label.setToolTip(self.trUtf8("Destination: %s" % self.output))
        self.bar = QProgressBar(parent)
        self.bar.setToolTip(self.trUtf8("Source: %s" % self.filename))
        self.bar.setValue(0)
        self.startbtn = QPushButton(parent) 
        self.stopbtn = QPushButton(parent)
        self.cancelbtn = QPushButton(parent)
        self.logbtn = QPushButton(parent)
        self.cancelbtn.setMinimumSize(32,32)
        self.cancelbtn.setFlat(True)
        self.startbtn.setMinimumSize(32,32)
        self.startbtn.setFlat(True)
        self.stopbtn.setMinimumSize(32,32)
        self.stopbtn.setFlat(True)
        self.label.setMinimumSize(200,32)
        self.bar.setMinimumSize(100,16)
        self.bar.setMaximumHeight(16)

        self.addWidget(self.logbtn)
        self.logbtn.hide()
        self.addWidget(self.label)
        self.addWidget(self.bar)
        self.addWidget(self.startbtn)
        self.addWidget(self.stopbtn)
        self.addWidget(self.cancelbtn)
        self.retranslateUi()

        self.connect(self.startbtn, SIGNAL("clicked()"), self.start)
        self.connect(self.stopbtn, SIGNAL("clicked()"),  self.stop)
        self.connect(self.cancelbtn, SIGNAL("clicked()"), self.remove)
        self.connect(self.logbtn, SIGNAL('clicked()'), self.showLog)
        self.connect(self.process, SIGNAL('progress(int)'), self.bar.setValue)
        self.connect(self.process, SIGNAL('error(QString)'), self.addLog)
        self.connect(self.process, SIGNAL('finished()'), self.enable)

    def retranslateUi(self):
        self.startbtn.setIcon(QIcon(u"images/play.png"))
        self.startbtn.setToolTip(self.trUtf8("Demarrer"))
        self.stopbtn.setIcon(QIcon(u"images/stop.png"))
        self.stopbtn.setToolTip(self.trUtf8("Stopper"))
        self.cancelbtn.setIcon(QIcon(u"images/remove.png"))
        self.cancelbtn.setToolTip(self.trUtf8("Annuler"))
        self.logbtn.setIcon(QIcon(u"images/log.png"))
        self.logbtn.setToolTip(self.trUtf8("Voir les details"))

    def start(self):
        self.log.clear()
        self.logbtn.hide()
        self.disable()
        self.process.start()
        self.process.resume()

    def stop(self):
        self.process.cancel()
        self.process.terminate()
        self.enable()

    def remove(self):
        self.removeWidget(self.label)
        self.removeWidget(self.bar)
        self.removeWidget(self.startbtn)
        self.removeWidget(self.stopbtn)
        self.removeWidget(self.cancelbtn)
        self.removeWidget(self.logbtn)
        self.label.hide()
        self.bar.hide()
        self.startbtn.hide()
        self.stopbtn.hide()
        self.cancelbtn.hide()
        self.logbtn.hide()
        self.emit(SIGNAL("void removed(QString)"), self.output)

    def showLog(self):
        QMessageBox.critical(None, u"Ooops", self.log.join("\n"))

    def addLog(self, log):
        self.log.append(log)
        self.logbtn.show()
        palette = QPalette()
        brush = QBrush(QColor(240, 100, 100))
        brush.setStyle(Qt.SolidPattern)
        palette.setBrush(QPalette.Normal, QPalette.Background, brush)
        self.label.setPalette(palette)
        self.label.setAutoFillBackground(True)

    def enable(self):
        self.process = SCJ(self.filename, self.format, self.createDir)
        self.output = QString(self.process.output)
        self.command = QStringList(self.process.output)
        self.connect(self.process, SIGNAL('progress(int)'), self.bar.setValue)
        self.connect(self.process, SIGNAL('error(QString)'), self.addLog)
        self.connect(self.process, SIGNAL('finished()'), self.enable)
        self.cancelbtn.setEnabled(True)
        self.startbtn.setEnabled(True)

    def disable(self):
        self.cancelbtn.setEnabled(False)
        self.startbtn.setEnabled(False)
        self.label.setAutoFillBackground(False)
예제 #22
0
    def __createLayout( self, scriptName, name, code, reportTime ):
        " Creates the toolbar and layout "

        # Buttons
        self.__printButton = QAction( PixmapCache().getIcon( 'printer.png' ),
                                      'Print', self )
        self.__printButton.triggered.connect( self.__onPrint )
        self.__printButton.setEnabled( False )
        self.__printButton.setVisible( False )

        self.__printPreviewButton = QAction(
                PixmapCache().getIcon( 'printpreview.png' ),
                'Print preview', self )
        self.__printPreviewButton.triggered.connect( self.__onPrintPreview )
        self.__printPreviewButton.setEnabled( False )
        self.__printPreviewButton.setVisible( False )

        # Zoom buttons
        self.__zoomInButton = QAction( PixmapCache().getIcon( 'zoomin.png' ),
                                       'Zoom in (Ctrl+=)', self )
        self.__zoomInButton.triggered.connect( self.onZoomIn )

        self.__zoomOutButton = QAction( PixmapCache().getIcon( 'zoomout.png' ),
                                        'Zoom out (Ctrl+-)', self )
        self.__zoomOutButton.triggered.connect( self.onZoomOut )

        self.__zoomResetButton = QAction( PixmapCache().getIcon( 'zoomreset.png' ),
                                          'Zoom reset (Ctrl+0)', self )
        self.__zoomResetButton.triggered.connect( self.onZoomReset )

        spacer = QWidget()
        spacer.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Expanding )

        # Toolbar
        toolbar = QToolBar( self )
        toolbar.setOrientation( Qt.Vertical )
        toolbar.setMovable( False )
        toolbar.setAllowedAreas( Qt.RightToolBarArea )
        toolbar.setIconSize( QSize( 16, 16 ) )
        toolbar.setFixedWidth( 28 )
        toolbar.setContentsMargins( 0, 0, 0, 0 )

        toolbar.addAction( self.__printPreviewButton )
        toolbar.addAction( self.__printButton )
        toolbar.addWidget( spacer )
        toolbar.addAction( self.__zoomInButton )
        toolbar.addAction( self.__zoomOutButton )
        toolbar.addAction( self.__zoomResetButton )

        summary = QLabel( "<b>Script:</b> " + scriptName + "<br>"
                          "<b>Name:</b> " + name + "<br>"
                          "<b>Disassembled at:</b> " + reportTime )
        summary.setFrameStyle( QFrame.StyledPanel )
        summary.setAutoFillBackground( True )
        summaryPalette = summary.palette()
        summaryBackground = summaryPalette.color( QPalette.Background )
        summaryBackground.setRgb( min( summaryBackground.red() + 30, 255 ),
                                  min( summaryBackground.green() + 30, 255 ),
                                  min( summaryBackground.blue() + 30, 255 ) )
        summaryPalette.setColor( QPalette.Background, summaryBackground )
        summary.setPalette( summaryPalette )

        self.__text = DisasmWidget( self )
        self.__text.setAcceptRichText( False )
        self.__text.setLineWrapMode( QTextEdit.NoWrap )
        self.__text.setFont( GlobalData().skin.nolexerFont )
        self.zoomTo( Settings().zoom )
        self.__text.setReadOnly( True )
        self.__text.setPlainText( code )

        vLayout = QVBoxLayout()
        vLayout.addWidget( summary )
        vLayout.addWidget( self.__text )

        hLayout = QHBoxLayout()
        hLayout.setContentsMargins( 0, 0, 0, 0 )
        hLayout.setSpacing( 0 )
        hLayout.addLayout( vLayout )
        hLayout.addWidget( toolbar )

        self.setLayout( hLayout )
        return
예제 #23
0
class MyMainWindow(QMainWindow):
    ' Main Window '
    def __init__(self, parent=None):
        super(MyMainWindow, self).__init__(parent)
        self.statusBar().showMessage(__doc__)
        self.setWindowTitle(__doc__)
        self.setMinimumSize(250, 280)
        self.setMaximumSize(300, 300)
        self.resize(250, 290)
        self.setWindowIcon(QIcon.fromTheme("face-monkey"))
        self.setStyleSheet('''QWidget { color: rgba( 0, 255, 255, 255 );
            background-color: #323232; font-family: 'Ubuntu Light';
            font-size: 14px;
            }

            QToolTip {
                border: 1px solid black;
                background-color: #ffa02f;
                background-image: None;
                padding: 1px;
                border-radius: 3px;
                opacity: 100;
            }

            QWidget:item:hover {
                background-color: QLinearGradient(
                    x1: 0, y1: 0,
                    x2: 0, y2: 1,
                    stop: 0 #ffa02f,
                    stop: 1 #ca0619
                );
                color: #000000;
            }

            QWidget:item:selected {
                background-color: QLinearGradient(
                    x1: 0, y1: 0,
                    x2: 0, y2: 1,
                    stop: 0 #ffa02f,
                    stop: 1 #d7801a
                );
            }

            QWidget:disabled {
                color: #404040;
                background-color: #323232;
            }

            QWidget:focus {
                background-image: None;
                border: 2px solid QLinearGradient(
                    x1: 0, y1: 0,
                    x2: 0, y2: 1,
                    stop: 0 #ffa02f,
                    stop: 1 #d7801a
                );
            }

            QPushButton {
                background-color: QLinearGradient(
                    x1: 0, y1: 0,
                    x2: 0, y2: 1,
                    stop: 0 #565656,
                    stop: 0.1 #525252,
                    stop: 0.5 #4e4e4e,
                    stop: 0.9 #4a4a4a,
                    stop: 1 #464646
                );
                border-width: 1px;
                border-color: #1e1e1e;
                border-style: solid;
                border-radius: 6;
                padding: 3px;
                font-size: 12px;
                padding-left: 5px;
                padding-right: 5px;
                background-image: None;
            }

            QPushButton:pressed {
                background-image: None;
                background-color: QLinearGradient(
                    x1: 0, y1: 0,
                    x2: 0, y2: 1,
                    stop: 0 #2d2d2d,
                    stop: 0.1 #2b2b2b,
                    stop: 0.5 #292929,
                    stop: 0.9 #282828,
                    stop: 1 #252525
                );
            }

            QComboBox {
                background-image: None;
                selection-background-color: #ffaa00;
                background-color: QLinearGradient(
                    x1: 0, y1: 0,
                    x2: 0, y2: 1,
                    stop: 0 #565656,
                    stop: 0.1 #525252,
                    stop: 0.5 #4e4e4e,
                    stop: 0.9 #4a4a4a,
                    stop: 1 #464646
                );
                border-style: solid;
                border: 1px solid #1e1e1e;
                border-radius: 5;
            }

            QComboBox:hover, QPushButton:hover {
                background-image: url(.bg.png);
                border: 2px solid QLinearGradient(
                    x1: 0, y1: 0,
                    x2: 0, y2: 1,
                    stop: 0 #ffa02f,
                    stop: 1 #d7801a
                );
            }

            QComboBox:on {
                padding-top: 3px;
                padding-left: 4px;
                background-color: QLinearGradient(
                    x1: 0, y1: 0,
                    x2: 0, y2: 1,
                    stop: 0 #2d2d2d,
                    stop: 0.1 #2b2b2b,
                    stop: 0.5 #292929,
                    stop: 0.9 #282828,
                    stop: 1 #252525
                );
                selection-background-color: #ffaa00;
                background-image: None;
            }

            QComboBox QAbstractItemView {
                background-image: None;
                border: 2px solid darkgray;
                selection-background-color: QLinearGradient(
                    x1: 0, y1: 0,
                    x2: 0, y2: 1,
                    stop: 0 #ffa02f,
                    stop: 1 #d7801a
                );
            }

            QComboBox::drop-down {
                 subcontrol-origin: padding;
                 subcontrol-position: top right;
                 width: 15px;
                 border-left-width: 0px;
                 border-left-color: darkgray;
                 border-left-style: solid;
                 border-top-right-radius: 3px;
                 border-bottom-right-radius: 3px;
                 background-image: None;
             }

            QComboBox::down-arrow { background-image: None; }

            QSlider {
                border-width: 2px;
                border-color: #1e1e1e;
                border-style: solid;
                padding: 3px;
                font-size: 8px;
                padding-left: 5px;
                padding-right: 5px;
                width: 25px;
                border-radius: 5px;
            }

            QSlider::sub-page:vertical {
                background: red;
                border: none;
                width: 25px;
            }

            QSlider::add-page:vertical {
                background: green;
                border: none;
                width: 25px;
            }

            QSlider::handle:vertical {
                background-color: QLinearGradient(spread:pad, x1:0, y1:0, x2:1,
                    y2:0.273, stop:0 rgba(0, 0, 0, 255),
                    stop:1 rgba(150, 255, 255, 255)
                    );
                width: 10px;
                height: 25px;
                border: 1px solid grey;
                text-align: center;
                border-top-left-radius: 2px;
                border-bottom-left-radius: 2px;
                border-top-right-radius: 2px;
                border-bottom-right-radius 2px;
                margin-left: 2px;
                margin-right: 2px;
            }

            QSlider::handle:vertical:hover {
                border: 2px solid #ffaa00;
                margin-left: 2px;
                margin-right: 2px;
            }

            QSlider::sub-page:vertical:disabled {
                background: #bbb;
                border-color: #999;
            }

            QSlider::add-page:vertical:disabled {
                background: #eee;
                border-color: #999;
            }

            QSlider::handle:vertical:disabled {
                background: #eee;
                border: 1px solid #aaa;
                border-radius: 4px;
            } ''')

        self.label1 = QLabel(self)
        self.label1.setText('Use Debug')
        self.label1.setGeometry(QtCore.QRect(25, 25, 125, 25))

        self.slider1 = QSlider(self)
        self.slider1.setGeometry(QtCore.QRect(150, 25, 25, 25))
        self.slider1.setTickInterval(1)
        self.slider1.setCursor(QCursor(QtCore.Qt.OpenHandCursor))
        self.slider1.TickPosition(QSlider.TicksBothSides)
        self.slider1.setRange(0, 1)
        self.slider1.setValue(1)
        self.sli1lbl = QLabel(str(self.slider1.value()), self.slider1)
        self.sli1lbl.move(9, 5)
        self.sli1lbl.setAutoFillBackground(False)
        self.slider1.valueChanged.connect(
            lambda: self.sli1lbl.setText(str(self.slider1.value())))
        self.slider1.sliderPressed.connect(
            lambda: self.slider1.setCursor(QCursor(QtCore.Qt.ClosedHandCursor)))
        self.slider1.sliderReleased.connect(
            lambda: self.slider1.setCursor(QCursor(QtCore.Qt.OpenHandCursor)))

        self.label2 = QLabel(self)
        self.label2.setText('Make Executable')
        self.label2.setGeometry(QtCore.QRect(25, 75, 125, 25))

        self.slider2 = QSlider(self)
        self.slider2.setGeometry(QtCore.QRect(150, 75, 25, 25))
        self.slider2.setTickInterval(1)
        self.slider2.setCursor(QCursor(QtCore.Qt.OpenHandCursor))
        self.slider2.TickPosition(QSlider.TicksBothSides)
        self.slider2.setRange(0, 1)
        self.slider2.setValue(1)
        self.sli2lbl = QLabel(str(self.slider2.value()), self.slider2)
        self.sli2lbl.move(9, 5)
        self.sli2lbl.setAutoFillBackground(False)
        self.slider2.valueChanged.connect(
            lambda: self.sli2lbl.setText(str(self.slider2.value())))
        self.slider2.sliderPressed.connect(
            lambda: self.slider2.setCursor(QCursor(QtCore.Qt.ClosedHandCursor)))
        self.slider2.sliderReleased.connect(
            lambda: self.slider2.setCursor(QCursor(QtCore.Qt.OpenHandCursor)))

        self.label3 = QLabel(self)
        self.label3.setText('Relative Imports')
        self.label3.setGeometry(QtCore.QRect(25, 125, 125, 25))

        self.slider3 = QSlider(self)
        self.slider3.setGeometry(QtCore.QRect(150, 125, 25, 25))
        self.slider3.setTickInterval(1)
        self.slider3.setCursor(QCursor(QtCore.Qt.OpenHandCursor))
        self.slider3.TickPosition(QSlider.TicksBothSides)
        self.slider3.setRange(0, 1)
        self.slider3.setValue(0)
        self.sli3lbl = QLabel(str(self.slider3.value()), self.slider3)
        self.sli3lbl.move(9, 5)
        self.sli3lbl.setAutoFillBackground(False)
        self.slider3.valueChanged.connect(
            lambda: self.sli3lbl.setText(str(self.slider3.value())))
        self.slider3.sliderPressed.connect(
            lambda: self.slider3.setCursor(QCursor(QtCore.Qt.ClosedHandCursor)))
        self.slider3.sliderReleased.connect(
            lambda: self.slider3.setCursor(QCursor(QtCore.Qt.OpenHandCursor)))

        self.label4 = QLabel(self)
        self.label4.setText('Indent Spaces')
        self.label4.setGeometry(QtCore.QRect(25, 175, 125, 25))

        self.combo1 = QComboBox(self)
        self.combo1.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
        self.combo1.addItems(['4', '0', '2', '6', '8'])
        self.combo1.setGeometry(QtCore.QRect(150, 175, 50, 25))

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setGeometry(QtCore.QRect(25, 225, 200, 32))
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel |
            QDialogButtonBox.Close | QDialogButtonBox.Help)
        self.buttonBox.setCenterButtons(False)
        self.buttonBox.helpRequested.connect(lambda: QMessageBox.about(
            self, __doc__, str(__doc__ + ', ' + ',\nversion ' + __version__ +
                               '(' + __license__ + '),\nby ' + __author__ + ', '
                               + __email__)))
        self.buttonBox.accepted.connect(self.run)
        self.buttonBox.rejected.connect(self.close)
        palette = self.palette()
        palette.setBrush(QPalette.Base, Qt.transparent)
        self.setPalette(palette)
        self.setAttribute(Qt.WA_OpaquePaintEvent, False)

    def run(self):
        'Run the actual conversion.'
        # Ask the User for the source .ui file as input
        filein = str(QFileDialog.getOpenFileName(
            self, __doc__, path.expanduser("~"), 'UI(*.ui)')).strip()
        # Parse Value of Slider1 as the Debug flag parameter
        if self.slider1.value() == 0:
            arg1 = ''
        else:
            arg1 = '--debug '
        # Parse Value of Slider2 as the Execute flag parameter
        if self.slider2.value() == 0:
            arg2 = ''
        else:
            arg2 = '--execute '
        # Parse Value of Slider3 as the relative imports flag parameter
        if self.slider3.value() == 0:
            arg3 = ''
        else:
            arg3 = '--from-imports '
        # debug
        #print(arg1, arg2, arg3, str(self.combo1.currentText()))
        # run the subprocesses
        subprocess.Popen(
            'nice --adjustment=19 pyuic4 ' + arg1 + arg2 + arg3 +
            '--indent=' + str(self.combo1.currentText()) +
            ' --output=' + str(filein).lower().replace('.ui', '.py') +
            ' ' + filein +
            ' && chmod -v +x ' + str(filein).lower().replace('.ui', '.py'),
            shell=True)

    def paintEvent(self, event):
        ' Paint semi-transparent background '
        painter = QPainter(self)
        painter.fillRect(event.rect(), Qt.transparent)
        painter.setPen(Qt.NoPen)
        painter.setBrush(QColor(0, 0, 0))
        painter.setOpacity(0.75)
        painter.drawRoundedRect(self.rect(), 75, 50)
        painter.end()
예제 #24
0
class RemoveSentencesDlg(QDialog):
	
	def __init__(self):
		super(RemoveSentencesDlg, self).__init__()
		self.removeList = {}
		self.initUI()
		
	def initUI(self):
		## create a font type for the label
		fontLabel = QFont('SansSerif', 14)
		## create a label 
		self.label = QLabel(self)
		self.label.setAutoFillBackground(True)
		self.label.setAlignment(Qt.AlignCenter)
		self.label.setGeometry(QRect(200, 10, 400, 40))
		self.label.setFont(fontLabel)
		
		## set the text for the Label
		self.label.setText('Remove the Sentences')
		
		## Create a Table to hold all the sentences
		self.sentenceTable = QTableWidget(self)
		## set the size and the position of the table
		self.sentenceTable.setGeometry(QRect(10, 60, 800, 400))
		
		## set the column count for the table
		self.sentenceTable.setColumnCount(1)
		
		sentenceHeaderList = ['Sentences From Table']
		
		self.sentenceTable.setHorizontalHeaderLabels(sentenceHeaderList)
		self.sentenceTable.resizeColumnsToContents()
		self.sentenceTable.horizontalHeader().setStretchLastSection(True)
		self.sentenceTable.verticalHeader().setStretchLastSection(True)
		
		# Create a Remove button
		self.removeButton = QPushButton('Remove', self)
		self.removeButton.move(350, 600)
		
		# Create a close button
		self.closeButton = QPushButton('Close', self)
		self.closeButton.move(450, 600)
		
		## Create signal for the remove button 
		self.connect(self.removeButton, SIGNAL("clicked()"), self.onRemoveClicked)
		
		## Create signal for the close button
		self.connect(self.closeButton, SIGNAL("clicked()"), self.closeClicked)
		
		## Create signal for the sentence table
		self.connect(self.sentenceTable, SIGNAL('cellClicked(int, int)'), self.sentenceStateChanged)
		
		## Get sentences from the database table
		self.getSentencesFromDatabase()
		
		
		self.setGeometry(800, 800, 900, 650)
		
	def getSentencesFromDatabase(self):
		## returns the sentence and the corresponding word associated with it
		self.twoTypeList = data.Data().getSentencesFromDatabase()
		if len(self.twoTypeList) == 2:
			self.sentenceList = self.twoTypeList[0]
			
		## load the sentences in the Table Widget
		self.loadSentencesInTable()
	
	def loadSentencesInTable(self):
		self.col = 0
		if len(self.sentenceList) > 0:
			self.sentenceTable.setRowCount(len(self.sentenceList))
			cellList = []
			## Create QTableWidgetItems from the sentence list
			for sentence in self.sentenceList:
				item = QTableWidgetItem(QString(sentence))
				item.setFlags(Qt.ItemFlags(Qt.ItemIsSelectable |
								Qt.ItemIsUserCheckable | Qt.ItemIsEnabled))
				item.setCheckState(Qt.Unchecked)
				cellList.append(item)
			cellList.reverse()
			# set the widget items in the table
			for item in range(0, len(self.sentenceList)):
				self.sentenceTable.setItem(item, self.col, cellList.pop())
			
			for index in range(0, len(self.sentenceList)):
				self.sentenceTable.verticalHeader().resizeSection(index, 100)
			
			if len(self.sentenceList) == 5:
				self.sentenceTable.setFixedHeight(500)
			if len(self.sentenceList) == 4:
				self.sentenceTable.setFixedHeight(400)
			elif len(self.sentenceList) == 3:
				self.sentenceTable.setFixedHeight(300)
			elif len(self.sentenceList) == 2:
				self.sentenceTable.setFixedHeight(200)
			elif len(self.sentenceList) == 1:
				self.sentenceTable.setFixedHeight(100)
		else:
			self.sentenceTable.clearContents()
		
	def sentenceStateChanged(self, row, col):
		if (self.sentenceTable.item(row, col).checkState() == 2):
			self.removeList[row] = self.sentenceTable.item(row, col).text()
			self.sentenceTable.item(row, col).setFlags(Qt.ItemFlags(Qt.ItemIsEditable |
									Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable))
		else:
			self.sentenceTable.item(row,col).setFlags(Qt.ItemFlags(Qt.ItemIsSelectable |
									Qt.ItemIsUserCheckable | Qt.ItemIsEnabled))
			del self.removeList[row]
	
	def onRemoveClicked(self):
		if len(self.removeList) == 0:
			QMessageBox.information(self, 'Remove Sentences',
					'Select the Sentences to Delete')
		else:
			reply = QMessageBox.question(self,
						'Remove Sentences',
						'You want to delete the selected sentences',
						QMessageBox.Yes | QMessageBox.No)
			if reply == QMessageBox.Yes:
				for sentence in self.removeList:
					if sentence in self.sentenceList:
						self.sentenceList.remove(sentence)
				
				## clear the contents of the Table
				self.sentenceTable.clearContents()
				
				cellList = []
				## Add the new entries into the table
				for sentence in self.sentenceList:
					item = QTableWidgetItem(QString(sentence))
					item.setFlags(Qt.ItemFlags(Qt.ItemIsSelectable |
									Qt.ItemIsUserCheckable | Qt.ItemIsEnabled))
					item.setCheckState(Qt.Unchecked)
					cellList.append(item)
				cellList.reverse()
				
				for index in range(0, len(self.sentenceList)):
					self.sentenceTable.setItem(index, self.col, cellList.pop())
					
				self.sentenceTable.setRowCount(len(self.sentenceList))
				
				deleteSentences = []
				for sentence in self.removeList.values():
					deleteSentences.append(sentence)
				
				rowsDeletec = data.Data().deleteSentencesFromDatabase(deleteSentences)
				self.getSentencesFromDatabase()
				
				self.removeList = {}
	
	def closeClicked(self):
		reply = QMessageBox.question(self,
				"Remove Sentences",
				"Do you want to close the application",
				QMessageBox.Yes | QMessageBox.No)
		if reply == QMessageBox.Yes:
			self.reject()
예제 #25
0
class TagHelpViewer( QWidget ):
    """ The tag help viewer widget """

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

        self.__isEmpty = True
        self.__copyAvailable = False
        self.__clearButton = None
        self.__textEdit = None
        self.__header = None
        self.__copyButton = None
        self.__selectAllButton = None
        self.__createLayout( parent )

        # create the context menu
        self.__menu = QMenu( self )
        self.__selectAllMenuItem = self.__menu.addAction(
                            PixmapCache().getIcon( 'selectall.png' ),
                            'Select All', self.__textEdit.selectAll )
        self.__copyMenuItem = self.__menu.addAction(
                            PixmapCache().getIcon( 'copytoclipboard.png' ),
                            'Copy', self.__textEdit.copy )
        self.__menu.addSeparator()
        self.__clearMenuItem = self.__menu.addAction(
                            PixmapCache().getIcon( 'trash.png' ),
                            'Clear', self.__clear )

        self.__textEdit.setContextMenuPolicy( Qt.CustomContextMenu )
        self.__textEdit.customContextMenuRequested.connect(
                                                self.__handleShowContextMenu )
        self.__textEdit.copyAvailable.connect( self.__onCopyAvailable )

        self.__updateToolbarButtons()
        return

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

        # __textEdit list area
        self.__textEdit = QPlainTextEdit( parent )
        self.__textEdit.setLineWrapMode( QPlainTextEdit.NoWrap )
        self.__textEdit.setFont( QFont( GlobalData().skin.baseMonoFontFace ) )
        self.__textEdit.setReadOnly( True )

        # Default font size is good enough for most of the systems.
        # 12.0 might be good only in case of the XServer on PC (Xming).
        # self.__textEdit.setFontPointSize( 12.0 )

        # Buttons
        self.__selectAllButton = QAction(
            PixmapCache().getIcon( 'selectall.png' ),
            'Select all', self )
        self.__selectAllButton.triggered.connect(self.__textEdit.selectAll )
        self.__copyButton = QAction(
            PixmapCache().getIcon( 'copytoclipboard.png' ),
            'Copy to clipboard', self )
        self.__copyButton.triggered.connect( self.__textEdit.copy )
        spacer = QWidget()
        spacer.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Expanding )
        self.__clearButton = QAction(
            PixmapCache().getIcon( 'trash.png' ),
            'Clear all', self )
        self.__clearButton.triggered.connect( self.__clear )

        # Toolbar
        toolbar = QToolBar()
        toolbar.setOrientation( Qt.Vertical )
        toolbar.setMovable( False )
        toolbar.setAllowedAreas( Qt.LeftToolBarArea )
        toolbar.setIconSize( QSize( 16, 16 ) )
        toolbar.setFixedWidth( 28 )
        toolbar.setContentsMargins( 0, 0, 0, 0 )
        toolbar.addAction( self.__selectAllButton )
        toolbar.addAction( self.__copyButton )
        toolbar.addWidget( spacer )
        toolbar.addAction( self.__clearButton )

        self.__header = QLabel( "Signature: none" )
        self.__header.setFrameStyle( QFrame.StyledPanel )
        self.__header.setSizePolicy( QSizePolicy.Ignored, QSizePolicy.Fixed )
        self.__header.setAutoFillBackground( True )
        headerPalette = self.__header.palette()
        headerBackground = headerPalette.color( QPalette.Background )
        headerBackground.setRgb( min( headerBackground.red() + 30, 255 ),
                                 min( headerBackground.green() + 30, 255 ),
                                 min( headerBackground.blue() + 30, 255 ) )
        headerPalette.setColor( QPalette.Background, headerBackground )
        self.__header.setPalette( headerPalette )
        verticalLayout = QVBoxLayout()
        verticalLayout.setContentsMargins( 2, 2, 2, 2 )
        verticalLayout.setSpacing( 2 )
        verticalLayout.addWidget( self.__header )
        verticalLayout.addWidget( self.__textEdit )

        # layout
        layout = QHBoxLayout()
        layout.setContentsMargins( 0, 0, 0, 0 )
        layout.setSpacing( 0 )
        layout.addWidget( toolbar )
        layout.addLayout( verticalLayout )

        self.setLayout( layout )
        return

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

        self.__selectAllMenuItem.setEnabled( not self.__isEmpty )
        self.__copyMenuItem.setEnabled( self.__copyAvailable )
        self.__clearMenuItem.setEnabled( not self.__isEmpty )

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

    def __calltipDisplayable( self, calltip ):
        " True if calltip is displayable "
        if calltip is None:
            return False
        if calltip.strip() == "":
            return False
        return True

    def __docstringDisplayable( self, docstring ):
        " True if docstring is displayable "
        if docstring is None:
            return False
        if isinstance( docstring, dict ):
            if docstring[ "docstring" ].strip() == "":
                return False
            return True
        if docstring.strip() == "":
            return False
        return True

    def display( self, calltip, docstring ):
        " Displays the given help information "

        calltipDisplayable = self.__calltipDisplayable( calltip )
        docstringDisplayable = self.__docstringDisplayable( docstring )
        self.__isEmpty = True
        if calltipDisplayable or docstringDisplayable:
            self.__isEmpty = False

        if calltipDisplayable:
            if '\n' in calltip:
                calltip = calltip.split( '\n' )[ 0 ]
            self.__header.setText( "Signature: " + calltip.strip() )
        else:
            self.__header.setText( "Signature: n/a" )

        self.__textEdit.clear()
        if docstringDisplayable:
            if isinstance( docstring, dict ):
                docstring = docstring[ "docstring" ]
            self.__textEdit.insertPlainText( docstring )

        self.__updateToolbarButtons()
        QApplication.processEvents()
        return

    def __updateToolbarButtons( self ):
        " Contextually updates toolbar buttons "

        self.__selectAllButton.setEnabled( not self.__isEmpty )
        self.__copyButton.setEnabled( self.__copyAvailable )
        self.__clearButton.setEnabled( not self.__isEmpty )
        return

    def __clear( self ):
        " Triggers when the clear function is selected "
        self.__isEmpty = True
        self.__copyAvailable = False
        self.__header.setText( "Signature: none" )
        self.__textEdit.clear()
        self.__updateToolbarButtons()
        return

    def __onCopyAvailable( self, isAvailable ):
        " Triggers on the copyAvailable signal "
        self.__copyAvailable = isAvailable
        self.__updateToolbarButtons()
        return
예제 #26
0
    def __addSimilarity( self, similarity, titleText ):
        " Adds a similarity "

        # Label
        title = QLabel( titleText )
        title.setFont( self.__headerFont )

        self.__vLayout.addWidget( title )
        self.__widgets.append( title )

        # List of files
        simTable = QTreeWidget( self.bodyWidget )
        simTable.setAlternatingRowColors( True )
        simTable.setRootIsDecorated( False )
        simTable.setItemsExpandable( False )
        simTable.setSortingEnabled( False )
        simTable.setItemDelegate( NoOutlineHeightDelegate( 4 ) )
        simTable.setUniformRowHeights( True )
        simTable.itemActivated.connect( self.__similarityActivated )
        simTable.setHeaderLabels( [ "File name", "Line" ] )

        for item in similarity.files:
            values = [ item[ 0 ], str( item[ 1 ] ) ]
            simTable.addTopLevelItem( QTreeWidgetItem( values )  )

        # Resizing
        simTable.header().resizeSections( QHeaderView.ResizeToContents )
        simTable.header().setStretchLastSection( True )

        # Height
        self.__setTableHeight( simTable )

        self.__vLayout.addWidget( simTable )
        self.__widgets.append( simTable )

        # The fragment itself
        if len( similarity.fragment ) > 10:
            # Take first 9 lines
            text = "\n".join( similarity.fragment[ : 9 ] ) + "\n ..."
            toolTip = "\n".join( similarity.fragment )
        else:
            text = "\n".join( similarity.fragment )
            toolTip = ""
        fragmentLabel = QLabel( "<pre>" + self.__htmlEncode( text ) + "</pre>" )
        if toolTip != "":
            fragmentLabel.setToolTip( "<pre>" + self.__htmlEncode( toolTip ) +
                                      "</pre>" )
        palette = fragmentLabel.palette()
        palette.setColor( QPalette.Background, QColor( 250, 250, 175 ) )
        palette.setColor( QPalette.Foreground, QColor( 0, 0, 0 ) )
        fragmentLabel.setPalette( palette )
        fragmentLabel.setFrameShape( QFrame.StyledPanel )
        fragmentLabel.setAutoFillBackground( True )

        labelFont = fragmentLabel.font()
        labelFont.setFamily( GlobalData().skin.baseMonoFontFace )
        fragmentLabel.setFont( labelFont )

        self.__vLayout.addWidget( fragmentLabel )
        self.__widgets.append( fragmentLabel )
        return
예제 #27
0
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        #self.setupUi(self)
        self.setWindowTitle(u'大图检测')
        #self.setFixedSize(1280,720)
        screen = QDesktopWidget().screenGeometry()
        #self.resize(screen.width(), screen.height())
        self.setFixedSize(screen.width() - 100, screen.height() - 100)
        self.center()
        ##########################背景层,使用绝对坐标########################
        palette = QPalette()
        self.setBackgroundandSize(self, './background.png',
                                  self.backgroundRole(), screen.height(),
                                  screen.width())

        ##########################标题部分,用的一张图片######################
        title = QLabel()
        self.setBackgroundandSize(title, './titlebg.png', QPalette.Window, 100,
                                  706)
        hboxTilte = QHBoxLayout()
        hboxTilte.addWidget(title)

        ##############################下方左侧#############################
        #########并列部分
        btnSelFile = QPushButton(u"选择文件")
        self.setBackgroundandSize(btnSelFile, './yellowbar.png',
                                  QPalette.Button, 23, 76)
        btnSelFile.setFlat(True)  #边缘消失
        editSelFile = QLineEdit(u"file:///")
        self.setBackgroundandSize(editSelFile, './greybar.png', QPalette.Base,
                                  23, 115)
        hboxSelFile = QHBoxLayout()
        hboxSelFile.addWidget(btnSelFile)
        hboxSelFile.addWidget(editSelFile)
        self.connect(
            btnSelFile,
            SIGNAL("clicked()"), lambda: self.button_openfile_click(
                Application.btncontrol, editSelFile, previewImg))
        hboxPicSize = QHBoxLayout()
        self.addRow(hboxPicSize, u"大图尺寸", u"宽:xxx 高:xxx", Application.leftSide)
        hboxOnlineNodes = QHBoxLayout()
        self.addRow(hboxOnlineNodes,
                    u"联机集群节点数",
                    u"xxx",
                    Application.leftSide,
                    smaller=True)
        hboxUsedNodes = QHBoxLayout()
        self.addRow(hboxUsedNodes,
                    u"使用集群节点数",
                    u"xxx",
                    Application.leftSide,
                    smaller=True)
        ########原图预览
        previewTxt = QLabel(u"原图预览")
        previewTxt.setFixedHeight(25)
        previewTxt.setFont(QFont("Times New Roman", 12))
        palette.setColor(QPalette.WindowText, Qt.yellow)
        previewTxt.setPalette(palette)
        previewTxt.setAlignment(Qt.AlignCenter)
        previewImg = QLabel()
        previewImg.setFixedHeight(0.3 * screen.height())
        previewImg.setFixedWidth(0.2 * screen.width())
        previewImg.setAutoFillBackground(True)
        previewImg.setAlignment(Qt.AlignCenter)
        image = QPixmap("./rawpic.png").scaled(previewImg.width(),
                                               previewImg.height())
        previewImg.setPixmap(image)
        #self.setBackgroundandSize(previewImg,'./rawpic.png',QPalette.Window,128,196)
        ########终端显示
        statusTxt = QLabel(u"集群终端状态")
        statusTxt.setFixedHeight(25)
        statusTxt.setFont(QFont("Times New Roman", 12))
        palette.setColor(QPalette.WindowText, Qt.yellow)
        statusTxt.setPalette(palette)
        statusTxt.setAlignment(Qt.AlignCenter)
        #statusImg = QLabel()
        #statusImg.setFixedHeight(0.3 * screen.height())
        #statusImg.setFixedWidth(0.2 * screen.width())
        #statusImg.setAutoFillBackground(True)
        #statusImg.setAlignment(Qt.AlignCenter)
        #palette.setColor(statusImg.backgroundRole(), Qt.black)
        #statusImg.setPalette(palette)
        #statusImg.setText("hello!")
        self.statusEdit = QTextEdit("python gui.py")
        statusEdit = self.statusEdit
        statusEdit.setFixedHeight(0.3 * screen.height())
        statusEdit.setFixedWidth(0.2 * screen.width())
        statusEdit.setAutoFillBackground(True)
        statusEdit.setAlignment(Qt.AlignLeft)
        palette.setColor(QPalette.Base, Qt.black)
        palette.setColor(QPalette.Text, Qt.yellow)
        statusEdit.setPalette(palette)
        #self.setBackgroundandSize(statusImg, './rawpic.png', QPalette.Window, 128, 196)
        ########以垂直的结构显示
        vboxleft = QVBoxLayout()
        vboxleft.addLayout(hboxSelFile)
        vboxleft.addLayout(hboxPicSize)
        vboxleft.addLayout(hboxOnlineNodes)
        vboxleft.addLayout(hboxUsedNodes)
        vboxleft.addWidget(previewTxt)
        vboxleft.addWidget(previewImg)
        vboxleft.addWidget(statusTxt)
        #vboxleft.addWidget(statusImg)
        vboxleft.addWidget(statusEdit)
        ###########################下方中间部分##########################
        ########控制按钮
        Application.btncontrol = QPushButton(u"将大图发送至集群")
        Application.btncontrol.setFont(QFont("Times New Roman", 12))
        Application.btncontrol.setEnabled(False)
        Application.btncontrol.setFixedHeight(25)
        Application.btncontrol.setFixedWidth(200)
        self.connect(Application.btncontrol, SIGNAL("clicked()"),
                     self.button_control_click)
        ########显示处理后的图片
        mid = QLabel()
        mid.setFixedHeight(440)
        mid.setFixedWidth(550)
        # palette.setColor(QPalette.Window, Qt.red)
        # mid.setAutoFillBackground(True)
        # mid.setPalette(palette)
        ########中间部分垂直布局
        vboxmid = QVBoxLayout()
        vboxmid.addWidget(Application.btncontrol)
        vboxmid.addWidget(mid)

        ##########################下方右侧部分############################
        ########三个返回值
        hboxTime = QHBoxLayout()
        self.addRow(hboxTime, u"运行时间", u"xxx", Application.rightSide)
        hboxPlanes = QHBoxLayout()
        self.addRow(hboxPlanes, u"飞机目标数", u"xxx", Application.rightSide)
        hboxShips = QHBoxLayout()
        self.addRow(hboxShips, u"舰船目标数", u"xxx", Application.rightSide)
        btnCoordFile = QPushButton(u"展示结果图")
        #self.setBackgroundandSize(btnCoordFile, './yellowbar2.png', QPalette.Button, 23, 115)
        btnCoordFile.setFlat(True)  # 边缘消失
        self.connect(btnCoordFile, SIGNAL("clicked()"),
                     self.button_show_click)  ###飞机船照片路径
        ########显示处理后的图片
        #coordFilePath = QLabel(u"file:///")
        #self.setBackgroundandSize(coordFilePath, './greybar.png', QPalette.Window, 23, 115)
        hboxCoordFile = QHBoxLayout()
        #hboxCoordFile.addWidget(coordFilePath)
        hboxCoordFile.addWidget(btnCoordFile)
        ########飞机
        self.planeImg = QLabel()
        planeImg = self.planeImg
        #planeImg.setAlignment(Qt.AlignCenter)
        #self.setBackgroundandSize(planeImg,'./rawpic2a.png',QPalette.Window,128,196)
        planeImg.setFixedHeight(0.3 * screen.height())
        planeImg.setFixedWidth(0.2 * screen.width())
        planeImg.setAutoFillBackground(True)
        planeImg.setAlignment(Qt.AlignCenter)
        planeimage = QPixmap("./rawpic2a.png").scaled(planeImg.width(),
                                                      planeImg.height())
        planeImg.setPixmap(planeimage)
        ########船
        self.shipImg = QLabel()
        shipImg = self.shipImg
        #shipImg.setAlignment(Qt.AlignCenter)
        #self.setBackgroundandSize(shipImg, './rawpic2b.png', QPalette.Window, 128, 196)
        shipImg.setFixedHeight(0.3 * screen.height())
        shipImg.setFixedWidth(0.2 * screen.width())
        shipImg.setAutoFillBackground(True)
        shipImg.setAlignment(Qt.AlignCenter)
        self.shipimage = QPixmap("./rawpic2b.png").scaled(
            shipImg.width(), shipImg.height())
        shipImg.setPixmap(self.shipimage)
        ########下方右侧布局
        vboxright = QVBoxLayout()
        vboxright.addLayout(hboxTime)
        vboxright.addLayout(hboxPlanes)
        vboxright.addLayout(hboxShips)
        vboxright.addLayout(hboxCoordFile)
        vboxright.addWidget(planeImg)
        vboxright.addWidget(shipImg)

        ##########################整体布局############################
        ########下方左中右
        hboxbody = QHBoxLayout()
        hboxbody.addLayout(vboxleft)
        hboxbody.addStretch(1)
        hboxbody.addLayout(vboxmid)
        hboxbody.addStretch(1)
        hboxbody.addLayout(vboxright)
        ########上下两部分
        vbox = QVBoxLayout()
        vbox.addLayout(hboxTilte)
        vbox.addStretch(0)
        vbox.addLayout(hboxbody)
        vbox.addStretch(1)
        self.setLayout(vbox)
예제 #28
0
class TagHelpViewer(QWidget):
    """ The tag help viewer widget """
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.__isEmpty = True
        self.__copyAvailable = False
        self.__clearButton = None
        self.__textEdit = None
        self.__header = None
        self.__copyButton = None
        self.__selectAllButton = None
        self.__createLayout(parent)

        # create the context menu
        self.__menu = QMenu(self)
        self.__selectAllMenuItem = self.__menu.addAction(
            PixmapCache().getIcon('selectall.png'), 'Select All',
            self.__textEdit.selectAll)
        self.__copyMenuItem = self.__menu.addAction(
            PixmapCache().getIcon('copytoclipboard.png'), 'Copy',
            self.__textEdit.copy)
        self.__menu.addSeparator()
        self.__clearMenuItem = self.__menu.addAction(
            PixmapCache().getIcon('trash.png'), 'Clear', self.__clear)

        self.__textEdit.setContextMenuPolicy(Qt.CustomContextMenu)
        self.__textEdit.customContextMenuRequested.connect(
            self.__handleShowContextMenu)
        self.__textEdit.copyAvailable.connect(self.__onCopyAvailable)

        self.__updateToolbarButtons()
        return

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

        # __textEdit list area
        self.__textEdit = QPlainTextEdit(parent)
        self.__textEdit.setLineWrapMode(QPlainTextEdit.NoWrap)
        self.__textEdit.setFont(QFont(GlobalData().skin.baseMonoFontFace))
        self.__textEdit.setReadOnly(True)

        # Default font size is good enough for most of the systems.
        # 12.0 might be good only in case of the XServer on PC (Xming).
        # self.__textEdit.setFontPointSize( 12.0 )

        # Buttons
        self.__selectAllButton = QAction(
            PixmapCache().getIcon('selectall.png'), 'Select all', self)
        self.__selectAllButton.triggered.connect(self.__textEdit.selectAll)
        self.__copyButton = QAction(
            PixmapCache().getIcon('copytoclipboard.png'), 'Copy to clipboard',
            self)
        self.__copyButton.triggered.connect(self.__textEdit.copy)
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.__clearButton = QAction(PixmapCache().getIcon('trash.png'),
                                     'Clear all', self)
        self.__clearButton.triggered.connect(self.__clear)

        # Toolbar
        toolbar = QToolBar()
        toolbar.setOrientation(Qt.Vertical)
        toolbar.setMovable(False)
        toolbar.setAllowedAreas(Qt.LeftToolBarArea)
        toolbar.setIconSize(QSize(16, 16))
        toolbar.setFixedWidth(28)
        toolbar.setContentsMargins(0, 0, 0, 0)
        toolbar.addAction(self.__selectAllButton)
        toolbar.addAction(self.__copyButton)
        toolbar.addWidget(spacer)
        toolbar.addAction(self.__clearButton)

        self.__header = QLabel("Signature: none")
        self.__header.setFrameStyle(QFrame.StyledPanel)
        self.__header.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
        self.__header.setAutoFillBackground(True)
        headerPalette = self.__header.palette()
        headerBackground = headerPalette.color(QPalette.Background)
        headerBackground.setRgb(min(headerBackground.red() + 30, 255),
                                min(headerBackground.green() + 30, 255),
                                min(headerBackground.blue() + 30, 255))
        headerPalette.setColor(QPalette.Background, headerBackground)
        self.__header.setPalette(headerPalette)
        verticalLayout = QVBoxLayout()
        verticalLayout.setContentsMargins(2, 2, 2, 2)
        verticalLayout.setSpacing(2)
        verticalLayout.addWidget(self.__header)
        verticalLayout.addWidget(self.__textEdit)

        # layout
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        layout.addWidget(toolbar)
        layout.addLayout(verticalLayout)

        self.setLayout(layout)
        return

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

        self.__selectAllMenuItem.setEnabled(not self.__isEmpty)
        self.__copyMenuItem.setEnabled(self.__copyAvailable)
        self.__clearMenuItem.setEnabled(not self.__isEmpty)

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

    def __calltipDisplayable(self, calltip):
        " True if calltip is displayable "
        if calltip is None:
            return False
        if calltip.strip() == "":
            return False
        return True

    def __docstringDisplayable(self, docstring):
        " True if docstring is displayable "
        if docstring is None:
            return False
        if isinstance(docstring, dict):
            if docstring["docstring"].strip() == "":
                return False
            return True
        if docstring.strip() == "":
            return False
        return True

    def display(self, calltip, docstring):
        " Displays the given help information "

        calltipDisplayable = self.__calltipDisplayable(calltip)
        docstringDisplayable = self.__docstringDisplayable(docstring)
        self.__isEmpty = True
        if calltipDisplayable or docstringDisplayable:
            self.__isEmpty = False

        if calltipDisplayable:
            if '\n' in calltip:
                calltip = calltip.split('\n')[0]
            self.__header.setText("Signature: " + calltip.strip())
        else:
            self.__header.setText("Signature: n/a")

        self.__textEdit.clear()
        if docstringDisplayable:
            if isinstance(docstring, dict):
                docstring = docstring["docstring"]
            self.__textEdit.insertPlainText(docstring)

        self.__updateToolbarButtons()
        QApplication.processEvents()
        return

    def __updateToolbarButtons(self):
        " Contextually updates toolbar buttons "

        self.__selectAllButton.setEnabled(not self.__isEmpty)
        self.__copyButton.setEnabled(self.__copyAvailable)
        self.__clearButton.setEnabled(not self.__isEmpty)
        return

    def __clear(self):
        " Triggers when the clear function is selected "
        self.__isEmpty = True
        self.__copyAvailable = False
        self.__header.setText("Signature: none")
        self.__textEdit.clear()
        self.__updateToolbarButtons()
        return

    def __onCopyAvailable(self, isAvailable):
        " Triggers on the copyAvailable signal "
        self.__copyAvailable = isAvailable
        self.__updateToolbarButtons()
        return
예제 #29
0
class PylintViewer( QWidget ):
    " Pylint tab widget "

    # Limits to colorize the final score
    BadLimit = 8.5
    GoodLimit = 9.5

    # Options of providing a report
    SingleFile     = 0
    DirectoryFiles = 1
    ProjectFiles   = 2
    SingleBuffer   = 3

    updatePylintTooltip = pyqtSignal( str )

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

        self.__reportUUID = ""
        self.__reportFileName = ""
        self.__reportOption = -1
        self.__reportShown = False
        self.__report = None

        self.__widgets = []

        # Prepare members for reuse
        if GlobalData().pylintAvailable:
            self.__noneLabel = QLabel( "\nNo results available" )
        else:
            self.__noneLabel = QLabel( "\nPylint is not available" )
        self.__noneLabel.setAutoFillBackground( True )
        noneLabelPalette = self.__noneLabel.palette()
        noneLabelPalette.setColor( QPalette.Background,
                                   GlobalData().skin.nolexerPaper )
        self.__noneLabel.setPalette( noneLabelPalette )

        self.__noneLabel.setFrameShape( QFrame.StyledPanel )
        self.__noneLabel.setAlignment( Qt.AlignHCenter )
        self.__headerFont = self.__noneLabel.font()
        self.__headerFont.setPointSize( self.__headerFont.pointSize() + 4 )
        self.__noneLabel.setFont( self.__headerFont )

        self.__createLayout( parent )

        self.__updateButtonsStatus()
        self.resizeEvent()
        return

    def __createLayout( self, parent ):
        " Creates the toolbar and layout "

        # Buttons
        self.printButton = QAction( PixmapCache().getIcon( 'printer.png' ),
                                    'Print', self )
        #printButton.setShortcut( 'Ctrl+' )
        self.printButton.triggered.connect( self.__onPrint )
        self.printButton.setVisible( False )

        self.printPreviewButton = QAction(
                PixmapCache().getIcon( 'printpreview.png' ),
                'Print preview', self )
        #printPreviewButton.setShortcut( 'Ctrl+' )
        self.printPreviewButton.triggered.connect( self.__onPrintPreview )
        self.printPreviewButton.setVisible( False )

        spacer = QWidget()
        spacer.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Expanding )

        self.clearButton = QAction(
            PixmapCache().getIcon( 'trash.png' ),
            'Clear', self )
        self.clearButton.triggered.connect( self.__clear )

        # The toolbar
        self.toolbar = QToolBar( self )
        self.toolbar.setOrientation( Qt.Vertical )
        self.toolbar.setMovable( False )
        self.toolbar.setAllowedAreas( Qt.RightToolBarArea )
        self.toolbar.setIconSize( QSize( 16, 16 ) )
        self.toolbar.setFixedWidth( 28 )
        self.toolbar.setContentsMargins( 0, 0, 0, 0 )

        self.toolbar.addAction( self.printPreviewButton )
        self.toolbar.addAction( self.printButton )
        self.toolbar.addWidget( spacer )
        self.toolbar.addAction( self.clearButton )

        self.__vLayout = QVBoxLayout()
        self.__vLayout.setContentsMargins( 5, 5, 5, 5 )
        self.__vLayout.setSpacing( 0 )
        self.__vLayout.setSizeConstraint( QLayout.SetFixedSize )

        self.__bodyFrame = QFrame( self )
#        self.__bodyFrame.setFrameShape( QFrame.StyledPanel )
        self.__bodyFrame.setFrameShape( QFrame.NoFrame )

#        self.__bodyFrame.setSizePolicy( QSizePolicy.Maximum,
#                                        QSizePolicy.Expanding )
        self.__bodyFrame.setLayout( self.__vLayout )
        self.bodyWidget = QScrollArea( self )
        self.bodyWidget.setFocusPolicy( Qt.NoFocus )
        self.bodyWidget.setWidget( self.__bodyFrame )
        self.bodyWidget.hide()

        self.__hLayout = QHBoxLayout()
        self.__hLayout.setContentsMargins( 0, 0, 0, 0 )
        self.__hLayout.setSpacing( 0 )
        self.__hLayout.addWidget( self.toolbar )
        self.__hLayout.addWidget( self.__noneLabel )
        self.__hLayout.addWidget( self.bodyWidget )

        self.setLayout( self.__hLayout )
        return

    def __updateButtonsStatus( self ):
        " Updates the buttons status "
        self.printButton.setEnabled( self.__reportShown )
        self.printPreviewButton.setEnabled( self.__reportShown )
        self.clearButton.setEnabled( self.__reportShown )
        return

    def __onPrint( self ):
        " Triggered when the print button is pressed "
        pass

    def __onPrintPreview( self ):
        " triggered when the print preview button is pressed "
        pass

    def setFocus( self ):
        " Overridden setFocus "
        self.__vLayout.setFocus()
        return

    def __clear( self ):
        " Clears the content of the vertical layout "
        if not self.__reportShown:
            return

        self.__removeAll()
        self.bodyWidget.hide()
        self.__noneLabel.show()

        self.__report = None
        self.__reportShown = False
        self.__updateButtonsStatus()
        self.resizeEvent()

        self.__updateTooltip()
        return

    def __removeAll( self ):
        " Removes all the items from the report "
        for item in self.__widgets:
            item.hide()
            self.__vLayout.removeWidget( item )
            del item

        self.__widgets = []
        return

    def __createScoreLabel( self, score, previousScore,
                            showFileName, fileName ):
        " Creates the score label "

        txt = "Score: " + str( score )
        if previousScore != "":
            txt += " / Previous score: " + str( previousScore )
        if not showFileName:
            txt += " for " + os.path.basename( fileName )

        scoreLabel = QLabel( txt )
        scoreLabel.setFrameShape( QFrame.StyledPanel )
        scoreLabel.setFont( self.__headerFont )
        scoreLabel.setAutoFillBackground( True )
        palette = scoreLabel.palette()

        if score < self.BadLimit:
            palette.setColor( QPalette.Background, QColor( 255, 127, 127 ) )
            palette.setColor( QPalette.Foreground, QColor( 0, 0, 0 ) )
        elif score > self.GoodLimit:
            palette.setColor( QPalette.Background, QColor( 220, 255, 220 ) )
            palette.setColor( QPalette.Foreground, QColor( 0, 0, 0 ) )
        else:
            palette.setColor( QPalette.Background, QColor( 255, 255, 127 ) )
            palette.setColor( QPalette.Foreground, QColor( 0, 0, 0 ) )

        scoreLabel.setPalette( palette )
        return scoreLabel

    @staticmethod
    def __setTableHeight( table ):
        " Auxiliary function to set the table height "

        # Height - it is ugly and approximate however I am tired of
        # calculating the proper height. Why is this so hard, huh?
        lastRowHeight = table.itemDelegate().lastHeight
        height = lastRowHeight * ( table.topLevelItemCount() + 1 ) + 10
        table.setFixedHeight( height )
        return

    @staticmethod
    def __shouldShowFileName( messages ):
        " Decides if the file name column should be supressed "
        if len( messages ) == 0:
            return False
        firstName = messages[ 0 ].fileName
        for index in range( 1, len( messages ) ):
            if firstName != messages[ index ].fileName:
                return True
        return False

    def __addErrorsTable( self, messages, showFileName ):
        " Creates the messages table "

        errTable = QTreeWidget( self.bodyWidget )
        errTable.setAlternatingRowColors( True )
        errTable.setRootIsDecorated( False )
        errTable.setItemsExpandable( False )
        errTable.setSortingEnabled( True )
        errTable.setItemDelegate( NoOutlineHeightDelegate( 4 ) )
        errTable.setUniformRowHeights( True )
        errTable.itemActivated.connect( self.__errorActivated )

        headerLabels = [ "File name", "Line", "Message ID", "Object", "Message" ]
        errTable.setHeaderLabels( headerLabels )

        for item in messages:
            if item.position is None:
                lineNumber = str( item.lineNumber )
            else:
                lineNumber = str( item.lineNumber ) + ":" + str( item.position )
            values = [ item.fileName, lineNumber, item.messageID,
                       item.objectName, item.message ]
            errTable.addTopLevelItem( ErrorTableItem( values, 1 ) )

        # Hide the file name column if required
        if not showFileName:
            errTable.setColumnHidden( 0, True )

        # Resizing
        errTable.header().resizeSections( QHeaderView.ResizeToContents )
        errTable.header().setStretchLastSection( True )

        # Sort indicator
        if showFileName:
            sortIndex = 0   # By file names
        else:
            sortIndex = 1   # By line number because this is from the same file
        errTable.header().setSortIndicator( sortIndex, Qt.AscendingOrder )
        errTable.sortItems( sortIndex, errTable.header().sortIndicatorOrder() )

        # Height
        self.__setTableHeight( errTable )

        self.__vLayout.addWidget( errTable )
        self.__widgets.append( errTable )
        return

    def __addSimilarity( self, similarity, titleText ):
        " Adds a similarity "

        # Label
        title = QLabel( titleText )
        title.setFont( self.__headerFont )

        self.__vLayout.addWidget( title )
        self.__widgets.append( title )

        # List of files
        simTable = QTreeWidget( self.bodyWidget )
        simTable.setAlternatingRowColors( True )
        simTable.setRootIsDecorated( False )
        simTable.setItemsExpandable( False )
        simTable.setSortingEnabled( False )
        simTable.setItemDelegate( NoOutlineHeightDelegate( 4 ) )
        simTable.setUniformRowHeights( True )
        simTable.itemActivated.connect( self.__similarityActivated )
        simTable.setHeaderLabels( [ "File name", "Line" ] )

        for item in similarity.files:
            values = [ item[ 0 ], str( item[ 1 ] ) ]
            simTable.addTopLevelItem( QTreeWidgetItem( values )  )

        # Resizing
        simTable.header().resizeSections( QHeaderView.ResizeToContents )
        simTable.header().setStretchLastSection( True )

        # Height
        self.__setTableHeight( simTable )

        self.__vLayout.addWidget( simTable )
        self.__widgets.append( simTable )

        # The fragment itself
        if len( similarity.fragment ) > 10:
            # Take first 9 lines
            text = "\n".join( similarity.fragment[ : 9 ] ) + "\n ..."
            toolTip = "\n".join( similarity.fragment )
        else:
            text = "\n".join( similarity.fragment )
            toolTip = ""
        fragmentLabel = QLabel( "<pre>" + self.__htmlEncode( text ) + "</pre>" )
        if toolTip != "":
            fragmentLabel.setToolTip( "<pre>" + self.__htmlEncode( toolTip ) +
                                      "</pre>" )
        palette = fragmentLabel.palette()
        palette.setColor( QPalette.Background, QColor( 250, 250, 175 ) )
        palette.setColor( QPalette.Foreground, QColor( 0, 0, 0 ) )
        fragmentLabel.setPalette( palette )
        fragmentLabel.setFrameShape( QFrame.StyledPanel )
        fragmentLabel.setAutoFillBackground( True )

        labelFont = fragmentLabel.font()
        labelFont.setFamily( GlobalData().skin.baseMonoFontFace )
        fragmentLabel.setFont( labelFont )

        self.__vLayout.addWidget( fragmentLabel )
        self.__widgets.append( fragmentLabel )
        return

    @staticmethod
    def __htmlEncode( string ):
        " Encodes HTML "
        return string.replace( "&", "&amp;" ) \
                     .replace( ">", "&gt;" ) \
                     .replace( "<", "&lt;" )

    def __addSectionSpacer( self ):
        " Adds a fixed height spacer to the VBox layout "
        spacer = QWidget()
        spacer.setFixedHeight( 10 )
        self.__vLayout.addWidget( spacer )
        self.__widgets.append( spacer )
        return

    def __addGenericTable( self, table ):
        " Adds a generic table to the report "

        theTable = QTreeWidget( self.bodyWidget )
        theTable.setAlternatingRowColors( True )
        theTable.setRootIsDecorated( False )
        theTable.setItemsExpandable( False )
        theTable.setSortingEnabled( False )
        theTable.setItemDelegate( NoOutlineHeightDelegate( 4 ) )
        theTable.setUniformRowHeights( True )

        headerLabels = []
        for index in range( 0, len( table.header ) ):
            headerLabels.append( table.header[ index ] )
        theTable.setHeaderLabels( headerLabels )

        for item in table.body:
            row = []
            for index in range( 0, len( table.header ) ):
                row.append( item[ index ] )
            theTable.addTopLevelItem( QTreeWidgetItem( row ) )

        theTable.setFocusPolicy( Qt.NoFocus )

        # Resizing
        theTable.header().resizeSections( QHeaderView.ResizeToContents )
        theTable.header().setStretchLastSection( True )

        # Height
        self.__setTableHeight( theTable )

        self.__vLayout.addWidget( theTable )
        self.__widgets.append( theTable )
        return

    def __addGenericTableTitle( self, table ):
        " Adds a generic table title "
        tableTitle = QLabel( table.title )
        tableTitle.setFont( self.__headerFont )

        self.__vLayout.addWidget( tableTitle )
        self.__widgets.append( tableTitle )
        return

    def __updateTooltip( self ):
        " Generates a signal with appropriate string message "
        if not self.__reportShown:
            tooltip = "No results available"
        elif self.__reportOption == self.DirectoryFiles:
            tooltip = "Report generated for directory: " + \
                      self.__reportFileName
        elif self.__reportOption == self.ProjectFiles:
            tooltip = "Report generated for the whole project"
        elif self.__reportOption == self.SingleFile:
            tooltip = "Report generated for file: " + self.__reportFileName
        elif self.__reportOption == self.SingleBuffer:
            tooltip = "Report generated for unsaved file: " + \
                      self.__reportFileName
        else:
            tooltip = ""
        self.updatePylintTooltip.emit( tooltip )
        return

    def showReport( self, lint, reportOption, fileName, uuid ):
        " Shows the pylint results "
        self.__removeAll()
        self.__noneLabel.hide()

        self.__report = lint
        self.__reportUUID = uuid
        self.__reportFileName = fileName
        self.__reportOption = reportOption

        showFileName = self.__shouldShowFileName( lint.errorMessages )

        scoreLabel = self.__createScoreLabel( lint.score, lint.previousScore,
                                              showFileName, fileName )
        self.__vLayout.addWidget( scoreLabel )
        self.__widgets.append( scoreLabel )

        if len( lint.errorMessages ) > 0:
            self.__addSectionSpacer()
            self.__addErrorsTable( lint.errorMessages, showFileName )

        index = 0
        for similarity in lint.similarities:
            self.__addSectionSpacer()
            self.__addSimilarity( similarity, "Similarity #" + str( index ) )
            index += 1

        for table in lint.tables:
            self.__addSectionSpacer()
            self.__addGenericTableTitle( table )
            self.__addGenericTable( table )

        self.bodyWidget.show()
        self.bodyWidget.ensureVisible( 0, 0, 0, 0 )
        self.__reportShown = True
        self.__updateButtonsStatus()
        self.__updateTooltip()

        # It helps, but why do I have flickering?
        QApplication.processEvents()
        self.__resizeBodyFrame()
        return

    def __errorActivated( self, item, column ):
        " Handles the double click (or Enter) on the item "

        linePos = str( item.text( 1 ) )
        if ":" in linePos:
            parts = linePos.split( ":" )
            lineNumber = int( parts[ 0 ] )
            pos = int( parts[ 1 ] )
        else:
            lineNumber = int( linePos )
            pos = 0

        if self.__reportOption in [ self.SingleFile, self.DirectoryFiles,
                                    self.ProjectFiles ]:
            fileName = str( item.text( 0 ) )
        else:
            # SingleBuffer
            if self.__reportFileName != "":
                if os.path.isabs( self.__reportFileName ):
                    fileName = self.__reportFileName
                else:
                    # Could be unsaved buffer, so try to search by the
                    mainWindow = GlobalData().mainWindow
                    widget = mainWindow.getWidgetByUUID( self.__reportUUID )
                    if widget is None:
                        logging.error( "The unsaved buffer has been closed" )
                        return
                    # The widget was found, so jump to the required
                    editor = widget.getEditor()
                    editor.gotoLine( lineNumber, pos )
                    editor.setFocus()
                    return

        GlobalData().mainWindow.openFile( fileName, lineNumber, pos )
        return

    def __resizeBodyFrame( self ):
        " Resizing the frame to occupy all available width "
        size = self.bodyWidget.maximumViewportSize()
        self.__bodyFrame.setMinimumWidth( size.width() - 16 )
        self.__bodyFrame.setMinimumHeight( size.height() )
        return

    def showEvent( self, showEv = None ):
        " Called when the widget is shown "
        self.__resizeBodyFrame()
        return

    def resizeEvent( self, resizeEv = None ):
        " Called when the main window gets resized "
        self.__resizeBodyFrame()
        return

    def onFileUpdated( self, fileName, uuid ):
        " Called when a buffer is saved or saved as "

        if not self.__reportShown:
            return
        if self.__reportUUID != uuid:
            return

        # Currently shown report is for the saved buffer
        # File name is expected being absolute
        self.__reportFileName = fileName
        self.updatePylintTooltip.emit( "Report generated for buffer saved as " +
                                       fileName )
        return

    def __similarityActivated( self, item, column ):
        " Triggered when a similarity is activated "
        fileName = str( item.text( 0 ) )
        lineNumber = int( item.text( 1 ) )
        GlobalData().mainWindow.openFile( fileName, lineNumber )
        return
예제 #30
0
class FileOutlineViewer( QWidget ):
    """ The file outline viewer widget """

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

        self.__editorsManager = editorsManager
        self.__mainWindow = parent
        self.__editorsManager.currentChanged.connect( self.__onTabChanged )
        self.connect( self.__editorsManager, SIGNAL( "tabClosed" ),
                      self.__onTabClosed )
        self.connect( self.__editorsManager, SIGNAL( 'bufferSavedAs' ),
                      self.__onSavedBufferAs )
        self.connect( self.__editorsManager, SIGNAL( 'fileTypeChanged' ),
                      self.__onFileTypeChanged )

        self.__outlineBrowsers = {}  # UUID -> OutlineAttributes
        self.__currentUUID = None
        self.__updateTimer = QTimer( self )
        self.__updateTimer.setSingleShot( True )
        self.__updateTimer.timeout.connect( self.__updateView )

        self.findButton = None
        self.outlineViewer = None
        self.toolbar = None
        self.__createLayout()

        self.__modifiedFormat = Settings().modifiedFormat

        # create the context menu
        self.__menu = QMenu( self )
        self.__findMenuItem = self.__menu.addAction(
                                PixmapCache().getIcon( 'findusage.png' ),
                                'Find where used', self.__findWhereUsed )
        return

    def setTooltips( self, switchOn ):
        " Sets the tooltips mode "
        for key in self.__outlineBrowsers:
            self.__outlineBrowsers[ key ].browser.setTooltips( switchOn )
        return

    def __connectOutlineBrowser( self, browser ):
        " Connects a new buffer signals "
        browser.setContextMenuPolicy( Qt.CustomContextMenu )
        browser.customContextMenuRequested.connect( self.__handleShowContextMenu )

        self.connect( browser,
                      SIGNAL( "selectionChanged" ),
                      self.__selectionChanged )
        return

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

        # Toolbar part - buttons
        self.findButton = QAction(
                PixmapCache().getIcon( 'findusage.png' ),
                'Find where highlighted item is used', self )
        self.findButton.setVisible( False )
        self.findButton.triggered.connect( self.__findWhereUsed )
        self.showParsingErrorsButton = QAction(
                PixmapCache().getIcon( 'showparsingerrors.png' ),
                'Show lexer/parser errors', self )
        self.showParsingErrorsButton.triggered.connect( self.__showParserError )
        self.showParsingErrorsButton.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.findButton )
        self.toolbar.addAction( self.showParsingErrorsButton )

        # Prepare members for reuse
        self.__noneLabel = QLabel( "\nNot a python file" )
        self.__noneLabel.setFrameShape( QFrame.StyledPanel )
        self.__noneLabel.setAlignment( Qt.AlignHCenter )
        headerFont = self.__noneLabel.font()
        headerFont.setPointSize( headerFont.pointSize() + 2 )
        self.__noneLabel.setFont( headerFont )
        self.__noneLabel.setAutoFillBackground( True )
        noneLabelPalette = self.__noneLabel.palette()
        noneLabelPalette.setColor( QPalette.Background,
                                   GlobalData().skin.nolexerPaper )
        self.__noneLabel.setPalette( noneLabelPalette )

        self.__layout = QVBoxLayout()
        self.__layout.setContentsMargins( 0, 0, 0, 0 )
        self.__layout.setSpacing( 0 )
        self.__layout.addWidget( self.toolbar )
        self.__layout.addWidget( self.__noneLabel )

        self.setLayout( self.__layout )
        return

    def __selectionChanged( self, index ):
        " Handles the changed selection "
        if index is None:
            self.__outlineBrowsers[ self.__currentUUID ].contentItem = None
        else:
            self.__outlineBrowsers[ self.__currentUUID ].contentItem = \
                self.__outlineBrowsers[
                        self.__currentUUID ].browser.model().item( index )

        self.__updateButtons()
        return

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

        browser = self.__outlineBrowsers[ self.__currentUUID ].browser
        index = browser.indexAt( coord )
        if not index.isValid():
            return

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

        contextItem = self.__outlineBrowsers[ self.__currentUUID ].contentItem
        if contextItem is None:
            return

        self.__findMenuItem.setEnabled( self.findButton.isEnabled() )

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

    def __goToDefinition( self ):
        " Jump to definition context menu handler "
        contextItem = self.__outlineBrowsers[ self.__currentUUID ].contentItem
        if contextItem is not None:
            self.__outlineBrowsers[
                        self.__currentUUID ].browser.openItem( contextItem )
        return

    def __findWhereUsed( self ):
        """ Find where used context menu handler """
        contextItem = self.__outlineBrowsers[ self.__currentUUID ].contentItem
        if contextItem is not None:
            GlobalData().mainWindow.findWhereUsed(
                    contextItem.getPath(),
                    contextItem.sourceObj )
        return

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

        self.findButton.setEnabled( False )

        contextItem = self.__outlineBrowsers[ self.__currentUUID ].contentItem
        if contextItem is None:
            return

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

    def __onTabChanged( self, index ):
        " Triggered when another tab becomes active "

        # If the timer is still active that means the tab was switched before
        # the handler had a chance to work. Therefore update the previous tab
        # first if so.
        if self.__updateTimer.isActive():
            self.__updateTimer.stop()
            self.__updateView()

        # Now, switch the outline browser to the new tab
        if index == -1:
            widget = self.__editorsManager.currentWidget()
        else:
            widget = self.__editorsManager.getWidgetByIndex( index )
        if widget is None:
            if self.__currentUUID is not None:
                self.__outlineBrowsers[ self.__currentUUID ].browser.hide()
                self.__currentUUID = None
            self.__noneLabel.show()
            self.showParsingErrorsButton.setEnabled( False )
            return
        if widget.getType() not in [ MainWindowTabWidgetBase.PlainTextEditor,
                                     MainWindowTabWidgetBase.VCSAnnotateViewer ]:
            if self.__currentUUID is not None:
                self.__outlineBrowsers[ self.__currentUUID ].browser.hide()
                self.__currentUUID = None
            self.__noneLabel.show()
            self.showParsingErrorsButton.setEnabled( False )
            return

        # This is text editor, detect the file type
        if widget.getFileType() not in [ PythonFileType, Python3FileType ]:
            if self.__currentUUID is not None:
                self.__outlineBrowsers[ self.__currentUUID ].browser.hide()
                self.__currentUUID = None
            self.__noneLabel.show()
            self.showParsingErrorsButton.setEnabled( False )
            return


        # This is a python file, check if we already have the parsed info in
        # the cache
        uuid = widget.getUUID()
        if uuid in self.__outlineBrowsers:
            # We have it, hide the current and show the existed
            if self.__currentUUID is not None:
                self.__outlineBrowsers[ self.__currentUUID ].browser.hide()
                self.__currentUUID = None
            else:
                self.__noneLabel.hide()
            self.__currentUUID = uuid
            self.__outlineBrowsers[ self.__currentUUID ].browser.show()

            info = self.__outlineBrowsers[ self.__currentUUID ].info
            self.showParsingErrorsButton.setEnabled( info.isOK != True )
            return

        # It is first time we are here, create a new
        editor = widget.getEditor()
        editor.SCEN_CHANGE.connect( self.__onBufferChanged )
        editor.cursorPositionChanged.connect( self.__cursorPositionChanged )
        info = getBriefModuleInfoFromMemory( editor.text() )

        self.showParsingErrorsButton.setEnabled( info.isOK != True )

        shortFileName = widget.getShortName()
        browser = OutlineBrowser( uuid, shortFileName, info, self )
        browser.setHeaderHighlight( info.isOK != True )
        self.__connectOutlineBrowser( browser )
        self.__layout.addWidget( browser )
        if self.__currentUUID is not None:
            self.__outlineBrowsers[ self.__currentUUID ].browser.hide()
            self.__currentUUID = None
        else:
            self.__noneLabel.hide()

        self.__currentUUID = uuid
        attributes = OutlineAttributes()
        attributes.browser = browser
        attributes.contextItem = None
        attributes.info = info
        attributes.shortFileName = shortFileName
        attributes.changed = False
        self.__outlineBrowsers[ self.__currentUUID ] = attributes
        self.__outlineBrowsers[ self.__currentUUID ].browser.show()
        return

    def getCurrentUsedInfo( self ):
        " Provides the info used to show the current outline window "
        if self.__currentUUID in self.__outlineBrowsers:
            return self.__outlineBrowsers[ self.__currentUUID ].info
        return None

    def __cursorPositionChanged( self, xpos, ypos ):
        " Triggered when a cursor position is changed "
        if self.__updateTimer.isActive():
            # If a file is very large and the cursor is moved
            # straight after changes this will delay the update till
            # the real pause.
            self.__updateTimer.stop()
            self.__updateTimer.start( 1500 )
        return

    def __onBufferChanged( self ):
        " Triggered when a change in the buffer is identified "
        if self.__currentUUID is None:
            return
        widget = self.__editorsManager.getWidgetByUUID(
                                        self.__currentUUID )
        if widget is None:
            return
        if widget.getEditor().ignoreBufferChangedSignal:
            return
        if self.__mainWindow.debugMode:
            return

        self.__updateTimer.stop()
        if self.__currentUUID in self.__outlineBrowsers:
            if self.__outlineBrowsers[ self.__currentUUID ].changed == False:
                self.__outlineBrowsers[ self.__currentUUID ].changed = True
                browser = self.__outlineBrowsers[ self.__currentUUID ].browser
                fName = self.__outlineBrowsers[ self.__currentUUID ].shortFileName
                title = self.__modifiedFormat % fName
                browser.model().sourceModel().updateRootData( 0, title )
        self.__updateTimer.start( 1500 )
        return

    def __updateView( self ):
        " Updates the view when a file is changed "
        self.__updateTimer.stop()
        info = self.getCurrentBufferInfo()
        if info is None:
            return

        self.showParsingErrorsButton.setEnabled( info.isOK != True )
        browser = self.__outlineBrowsers[ self.__currentUUID ].browser
        fName = self.__outlineBrowsers[ self.__currentUUID ].shortFileName
        browser.setHeaderHighlight( info.isOK != True )

        if not info.isOK:
            title = self.__modifiedFormat % fName
            browser.model().sourceModel().updateRootData( 0, title )
            return

        browser.model().sourceModel().updateRootData( 0, fName )
        self.__outlineBrowsers[ self.__currentUUID ].changed = False

        browser.updateFileItem( browser.model().sourceModel().rootItem, info )
        self.__outlineBrowsers[ self.__currentUUID ].info = info

        return

    def getCurrentBufferInfo( self ):
        " Provides the current buffer parsed info "
        if self.__currentUUID is None:
            return None
        widget = self.__editorsManager.getWidgetByUUID( self.__currentUUID )
        if widget is None:
            return None

        editor = widget.getEditor()
        info = getBriefModuleInfoFromMemory( editor.text() )
        return info

    def __onTabClosed( self, uuid ):
        " Triggered when a tab is closed "

        if uuid in self.__outlineBrowsers:
            del self.__outlineBrowsers[ uuid ]
        return

    def __onSavedBufferAs( self, fileName, uuid ):
        " Triggered when a file is saved with a new name "

        if uuid in self.__outlineBrowsers:

            baseName = os.path.basename( fileName )
            if detectFileType( fileName ) not in [ PythonFileType,
                                                   Python3FileType ]:
                # It's not a python file anymore
                if uuid == self.__currentUUID:
                    self.__outlineBrowsers[ uuid ].browser.hide()
                    self.__noneLabel.show()
                    self.__currentUUID = None

                del self.__outlineBrowsers[ uuid ]
                self.showParsingErrorsButton.setEnabled( False )
                self.findButton.setEnabled( False )
                return

            # Still python file with a different name
            browser = self.__outlineBrowsers[ uuid ].browser
            self.__outlineBrowsers[ uuid ].shortFileName = baseName
            if self.__outlineBrowsers[ uuid ].changed:
                title = self.__modifiedFormat % baseName
            else:
                title = baseName
            browser.model().sourceModel().updateRootData( 0, title )
        return

    def __onFileTypeChanged( self, fileName, uuid, newFileType ):
        " Triggered when the current buffer file type is changed, e.g. .cgi "
        if newFileType in [ PythonFileType, Python3FileType ]:
            # The file became a python one
            if uuid not in self.__outlineBrowsers:
                self.__onTabChanged( -1 )
        else:
            if uuid in self.__outlineBrowsers:
                # It's not a python file any more
                if uuid == self.__currentUUID:
                    self.__outlineBrowsers[ uuid ].browser.hide()
                    self.__noneLabel.show()
                    self.__currentUUID = None

                del self.__outlineBrowsers[ uuid ]
                self.showParsingErrorsButton.setEnabled( False )
                self.findButton.setEnabled( False )
        return

    def __showParserError( self ):
        " Shows the parser errors window "
        if self.__currentUUID is None:
            return

        try:
            fName = self.__outlineBrowsers[ self.__currentUUID ].shortFileName

            widget = self.__editorsManager.getWidgetByUUID( self.__currentUUID )
            if widget is None:
                return

            editor = widget.getEditor()
            info = getBriefModuleInfoFromMemory( editor.text() )
            dialog = ParserErrorsDialog( fName, info )
            dialog.exec_()
        except Exception, ex:
            logging.error( str( ex ) )
        return