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
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())
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()
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
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
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
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( "&", "&" ) \ .replace( ">", ">" ) \ .replace( "<", "<" ) 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
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
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
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()
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
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
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
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
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
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
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
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
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)
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
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()
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()
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
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
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)
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
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( "&", "&" ) \ .replace( ">", ">" ) \ .replace( "<", "<" ) 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
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