def __createLayout(self): """Creates the toolbar and layout""" # Buttons printButton = QAction(getIcon('printer.png'), 'Print', self) printButton.triggered.connect(self.__onPrint) printButton.setEnabled(False) printButton.setVisible(False) printPreviewButton = QAction(getIcon('printpreview.png'), 'Print preview', self) printPreviewButton.triggered.connect(self.__onPrintPreview) printPreviewButton.setEnabled(False) printPreviewButton.setVisible(False) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) # The 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(printPreviewButton) toolbar.addAction(printButton) toolbar.addWidget(spacer) self.__importsBar = ImportListWidget(self.__viewer) self.__importsBar.hide() hLayout = QHBoxLayout() hLayout.setContentsMargins(0, 0, 0, 0) hLayout.setSpacing(0) hLayout.addWidget(self.__viewer) hLayout.addWidget(toolbar) self.setLayout(hLayout)
def __createLayout(self, bpointsModel): """Creates the widget layout""" verticalLayout = QVBoxLayout(self) verticalLayout.setContentsMargins(0, 0, 0, 0) verticalLayout.setSpacing(0) self.headerFrame = QFrame() self.headerFrame.setObjectName('bpheader') self.headerFrame.setStyleSheet('QFrame#bpheader {' + getLabelStyle(self) + '}') self.headerFrame.setFixedHeight(HEADER_HEIGHT) self.__breakpointLabel = QLabel("Breakpoints") headerLayout = QHBoxLayout() headerLayout.setContentsMargins(0, 0, 0, 0) headerLayout.addSpacing(3) headerLayout.addWidget(self.__breakpointLabel) self.headerFrame.setLayout(headerLayout) self.bpointsList = BreakPointView(self, bpointsModel) self.__editButton = QAction(getIcon('bpprops.png'), "Edit breakpoint properties", self) self.__editButton.triggered.connect(self.__onEdit) self.__editButton.setEnabled(False) self.__jumpToCodeButton = QAction(getIcon('gotoline.png'), "Jump to the code", self) self.__jumpToCodeButton.triggered.connect(self.__onJumpToCode) self.__jumpToCodeButton.setEnabled(False) self.__enableButton = QAction(getIcon('bpenable.png'), "Enable selected breakpoint", self) self.__enableButton.triggered.connect(self.__onEnableDisable) self.__enableButton.setEnabled(False) self.__disableButton = QAction(getIcon('bpdisable.png'), "Disable selected breakpoint", self) self.__disableButton.triggered.connect(self.__onEnableDisable) self.__disableButton.setEnabled(False) self.__enableAllButton = QAction(getIcon('bpenableall.png'), "Enable all the breakpoint", self) self.__enableAllButton.triggered.connect(self.__onEnableAll) self.__enableAllButton.setEnabled(False) self.__disableAllButton = QAction(getIcon('bpdisableall.png'), "Disable all the breakpoint", self) self.__disableAllButton.triggered.connect(self.__onDisableAll) self.__disableAllButton.setEnabled(False) self.__delButton = QAction(getIcon('delitem.png'), "Delete selected breakpoint", self) self.__delButton.triggered.connect(self.__onDel) self.__delButton.setEnabled(False) self.__delAllButton = QAction(getIcon('bpdelall.png'), "Delete all the breakpoint", self) self.__delAllButton.triggered.connect(self.__onDelAll) self.__delAllButton.setEnabled(False) # Toolbar self.toolbar = QToolBar() self.toolbar.setOrientation(Qt.Horizontal) 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.__editButton) self.toolbar.addAction(self.__jumpToCodeButton) fixedSpacer2 = QWidget() fixedSpacer2.setFixedWidth(5) self.toolbar.addWidget(fixedSpacer2) self.toolbar.addAction(self.__enableButton) self.toolbar.addAction(self.__enableAllButton) fixedSpacer3 = QWidget() fixedSpacer3.setFixedWidth(5) self.toolbar.addWidget(fixedSpacer3) self.toolbar.addAction(self.__disableButton) self.toolbar.addAction(self.__disableAllButton) expandingSpacer = QWidget() expandingSpacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) fixedSpacer4 = QWidget() fixedSpacer4.setFixedWidth(5) self.toolbar.addWidget(fixedSpacer4) self.toolbar.addWidget(expandingSpacer) self.toolbar.addAction(self.__delButton) fixedSpacer5 = QWidget() fixedSpacer5.setFixedWidth(5) self.toolbar.addWidget(fixedSpacer5) self.toolbar.addAction(self.__delAllButton) verticalLayout.addWidget(self.headerFrame) verticalLayout.addWidget(self.toolbar) verticalLayout.addWidget(self.bpointsList)
def __createToolbar(self): """Creates 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(30) self.__toolbar.setContentsMargins(0, 0, 0, 0) # Buttons saveAsMenu = QMenu(self) saveAsSVGAct = saveAsMenu.addAction(getIcon('filesvg.png'), 'Save as SVG...') saveAsSVGAct.triggered.connect(self.onSaveAsSVG) saveAsPDFAct = saveAsMenu.addAction(getIcon('filepdf.png'), 'Save as PDF...') saveAsPDFAct.triggered.connect(self.onSaveAsPDF) saveAsPNGAct = saveAsMenu.addAction(getIcon('filepixmap.png'), 'Save as PNG...') saveAsPNGAct.triggered.connect(self.onSaveAsPNG) saveAsMenu.addSeparator() saveAsCopyToClipboardAct = saveAsMenu.addAction( getIcon('copymenu.png'), 'Copy to clipboard') saveAsCopyToClipboardAct.triggered.connect(self.copyToClipboard) self.__saveAsButton = QToolButton(self) self.__saveAsButton.setIcon(getIcon('saveasmenu.png')) self.__saveAsButton.setToolTip('Save as') self.__saveAsButton.setPopupMode(QToolButton.InstantPopup) self.__saveAsButton.setMenu(saveAsMenu) self.__saveAsButton.setFocusPolicy(Qt.NoFocus) self.__levelUpButton = QToolButton(self) self.__levelUpButton.setFocusPolicy(Qt.NoFocus) self.__levelUpButton.setIcon(getIcon('levelup.png')) self.__levelUpButton.setToolTip('Smart zoom level up (Shift+wheel)') self.__levelUpButton.clicked.connect(self.onSmartZoomLevelUp) self.__levelIndicator = QLabel('<b>0</b>', self) self.__levelIndicator.setAlignment(Qt.AlignCenter) self.__levelDownButton = QToolButton(self) self.__levelDownButton.setFocusPolicy(Qt.NoFocus) self.__levelDownButton.setIcon(getIcon('leveldown.png')) self.__levelDownButton.setToolTip('Smart zoom level down (Shift+wheel)') self.__levelDownButton.clicked.connect(self.onSmartZoomLevelDown) fixedSpacer = QWidget() fixedSpacer.setFixedHeight(10) self.__hideDocstrings = QToolButton(self) self.__hideDocstrings.setCheckable(True) self.__hideDocstrings.setIcon(getIcon('hidedocstrings.png')) self.__hideDocstrings.setToolTip('Show/hide docstrings') self.__hideDocstrings.setFocusPolicy(Qt.NoFocus) self.__hideDocstrings.setChecked(Settings()['hidedocstrings']) self.__hideDocstrings.clicked.connect(self.__onHideDocstrings) self.__hideComments = QToolButton(self) self.__hideComments.setCheckable(True) self.__hideComments.setIcon(getIcon('hidecomments.png')) self.__hideComments.setToolTip('Show/hide comments') self.__hideComments.setFocusPolicy(Qt.NoFocus) self.__hideComments.setChecked(Settings()['hidecomments']) self.__hideComments.clicked.connect(self.__onHideComments) self.__hideExcepts = QToolButton(self) self.__hideExcepts.setCheckable(True) self.__hideExcepts.setIcon(getIcon('hideexcepts.png')) self.__hideExcepts.setToolTip('Show/hide except blocks') self.__hideExcepts.setFocusPolicy(Qt.NoFocus) self.__hideExcepts.setChecked(Settings()['hideexcepts']) self.__hideExcepts.clicked.connect(self.__onHideExcepts) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.__toolbar.addWidget(self.__saveAsButton) self.__toolbar.addWidget(spacer) self.__toolbar.addWidget(self.__levelUpButton) self.__toolbar.addWidget(self.__levelIndicator) self.__toolbar.addWidget(self.__levelDownButton) self.__toolbar.addWidget(fixedSpacer) self.__toolbar.addWidget(self.__hideDocstrings) self.__toolbar.addWidget(self.__hideComments) self.__toolbar.addWidget(self.__hideExcepts) return self.__toolbar
def __createLayout(self): """Creates the toolbar and layout""" # Buttons printButton = QAction(getIcon('printer.png'), 'Print (Ctrl+P)', self) printButton.triggered.connect(self.__onPrint) printPreviewButton = QAction(getIcon('printpreview.png'), 'Print preview', self) printPreviewButton.triggered.connect(self.__onPrintPreview) printPreviewButton.setEnabled(False) printPreviewButton.setVisible(False) printSpacer = QWidget() printSpacer.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) printSpacer.setFixedHeight(8) # Imports diagram and its menu importsMenu = QMenu(self) importsDlgAct = importsMenu.addAction(getIcon('detailsdlg.png'), 'Fine tuned imports diagram') importsDlgAct.triggered.connect(self.onImportDgmTuned) self.importsDiagramButton = QToolButton(self) self.importsDiagramButton.setIcon(getIcon('importsdiagram.png')) self.importsDiagramButton.setToolTip('Generate imports diagram') self.importsDiagramButton.setPopupMode(QToolButton.DelayedPopup) self.importsDiagramButton.setMenu(importsMenu) self.importsDiagramButton.setFocusPolicy(Qt.NoFocus) self.importsDiagramButton.clicked.connect(self.onImportDgm) self.importsDiagramButton.setEnabled(False) # Run script and its menu runScriptMenu = QMenu(self) runScriptDlgAct = runScriptMenu.addAction(getIcon('detailsdlg.png'), 'Set run/debug parameters') runScriptDlgAct.triggered.connect(self.onRunScriptDlg) self.runScriptButton = QToolButton(self) self.runScriptButton.setIcon(getIcon('run.png')) self.runScriptButton.setToolTip('Run script') self.runScriptButton.setPopupMode(QToolButton.DelayedPopup) self.runScriptButton.setMenu(runScriptMenu) self.runScriptButton.setFocusPolicy(Qt.NoFocus) self.runScriptButton.clicked.connect(self.onRunScript) self.runScriptButton.setEnabled(False) # Profile script and its menu profileScriptMenu = QMenu(self) profileScriptDlgAct = profileScriptMenu.addAction( getIcon('detailsdlg.png'), 'Set profile parameters') profileScriptDlgAct.triggered.connect(self.onProfileScriptDlg) self.profileScriptButton = QToolButton(self) self.profileScriptButton.setIcon(getIcon('profile.png')) self.profileScriptButton.setToolTip('Profile script') self.profileScriptButton.setPopupMode(QToolButton.DelayedPopup) self.profileScriptButton.setMenu(profileScriptMenu) self.profileScriptButton.setFocusPolicy(Qt.NoFocus) self.profileScriptButton.clicked.connect(self.onProfileScript) self.profileScriptButton.setEnabled(False) # Debug script and its menu debugScriptMenu = QMenu(self) debugScriptDlgAct = debugScriptMenu.addAction( getIcon('detailsdlg.png'), 'Set run/debug parameters') debugScriptDlgAct.triggered.connect(self.onDebugScriptDlg) self.debugScriptButton = QToolButton(self) self.debugScriptButton.setIcon(getIcon('debugger.png')) self.debugScriptButton.setToolTip('Debug script') self.debugScriptButton.setPopupMode(QToolButton.DelayedPopup) self.debugScriptButton.setMenu(debugScriptMenu) self.debugScriptButton.setFocusPolicy(Qt.NoFocus) self.debugScriptButton.clicked.connect(self.onDebugScript) self.debugScriptButton.setEnabled(False) # Disassembling disasmScriptMenu = QMenu(self) disasmScriptMenu.addAction(getIcon(''), 'Disassembly (no optimization)', self.__editor._onDisasm0) disasmScriptMenu.addAction(getIcon(''), 'Disassembly (optimization level 1)', self.__editor._onDisasm1) disasmScriptMenu.addAction(getIcon(''), 'Disassembly (optimization level 2)', self.__editor._onDisasm2) self.disasmScriptButton = QToolButton(self) self.disasmScriptButton.setIcon(getIcon('disassembly.png')) self.disasmScriptButton.setToolTip('Disassembly script') self.disasmScriptButton.setPopupMode(QToolButton.DelayedPopup) self.disasmScriptButton.setMenu(disasmScriptMenu) self.disasmScriptButton.setFocusPolicy(Qt.NoFocus) self.disasmScriptButton.clicked.connect(self.__editor._onDisasm0) self.disasmScriptButton.setEnabled(False) # Dead code self.deadCodeScriptButton = QAction(getIcon('deadcode.png'), 'Find dead code', self) self.deadCodeScriptButton.triggered.connect(self.__onDeadCode) self.deadCodeScriptButton.setEnabled(False) undoSpacer = QWidget() undoSpacer.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) undoSpacer.setFixedHeight(8) self.__undoButton = QAction(getIcon('undo.png'), 'Undo (Ctrl+Z)', self) self.__undoButton.setShortcut('Ctrl+Z') self.__undoButton.triggered.connect(self.__editor.onUndo) self.__undoButton.setEnabled(False) self.__redoButton = QAction(getIcon('redo.png'), 'Redo (Ctrl+Y)', self) self.__redoButton.setShortcut('Ctrl+Y') self.__redoButton.triggered.connect(self.__editor.onRedo) self.__redoButton.setEnabled(False) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.removeTrailingSpacesButton = QAction(getIcon('trailingws.png'), 'Remove trailing spaces', self) self.removeTrailingSpacesButton.triggered.connect( self.onRemoveTrailingWS) self.expandTabsButton = QAction(getIcon('expandtabs.png'), 'Expand tabs (4 spaces)', self) self.expandTabsButton.triggered.connect(self.onExpandTabs) # The toolbar toolbar = QToolBar(self) toolbar.setOrientation(Qt.Vertical) toolbar.setMovable(False) toolbar.setAllowedAreas(Qt.RightToolBarArea) toolbar.setIconSize(QSize(16, 16)) toolbar.setFixedWidth(30) toolbar.setContentsMargins(0, 0, 0, 0) toolbar.addAction(printPreviewButton) toolbar.addAction(printButton) toolbar.addWidget(printSpacer) toolbar.addWidget(self.importsDiagramButton) toolbar.addWidget(self.runScriptButton) toolbar.addWidget(self.profileScriptButton) toolbar.addWidget(self.debugScriptButton) toolbar.addWidget(self.disasmScriptButton) toolbar.addAction(self.deadCodeScriptButton) toolbar.addWidget(undoSpacer) toolbar.addAction(self.__undoButton) toolbar.addAction(self.__redoButton) toolbar.addWidget(spacer) toolbar.addAction(self.removeTrailingSpacesButton) toolbar.addAction(self.expandTabsButton) self.importsBar = ImportListWidget(self.__editor) self.importsBar.hide() self.__outsideChangesBar = OutsideChangeWidget(self.__editor) self.__outsideChangesBar.sigReloadRequest.connect(self.__onReload) self.__outsideChangesBar.reloadAllNonModifiedRequest.connect( self.reloadAllNonModified) self.__outsideChangesBar.hide() hLayout = QHBoxLayout() hLayout.setContentsMargins(0, 0, 0, 0) hLayout.setSpacing(0) vLayout = QVBoxLayout() vLayout.setContentsMargins(0, 0, 0, 0) vLayout.setSpacing(0) self.__navigationBar = NavigationBar(self.__editor, self) vLayout.addWidget(self.__navigationBar) vLayout.addWidget(self.__editor) hLayout.addLayout(vLayout) hLayout.addWidget(toolbar) widget = QWidget() widget.setLayout(hLayout) self.__splitter = QSplitter(Qt.Horizontal, self) self.__flowUI = FlowUIWidget(self.__editor, self) self.__mdView = MDWidget(self.__editor, self) self.__renderLayout = QVBoxLayout() self.__renderLayout.setContentsMargins(0, 0, 0, 0) self.__renderLayout.setSpacing(0) self.__renderLayout.addWidget(self.__flowUI) self.__renderLayout.addWidget(self.__mdView) self.__renderWidget = QWidget() self.__renderWidget.setLayout(self.__renderLayout) self.__splitter.addWidget(widget) self.__splitter.addWidget(self.__renderWidget) containerLayout = QHBoxLayout() containerLayout.setContentsMargins(0, 0, 0, 0) containerLayout.setSpacing(0) containerLayout.addWidget(self.__splitter) self.setLayout(containerLayout) self.__renderWidget.setVisible(False) self.__splitter.setSizes(Settings()['flowSplitterSizes']) self.__splitter.splitterMoved.connect(self.flowSplitterMoved) Settings().sigFlowSplitterChanged.connect(self.otherFlowSplitterMoved)
class ControlFlowNavigationBar(QFrame): """Navigation bar at the top of the flow UI widget""" STATE_OK_UTD = 0 # Parsed OK, control flow up to date STATE_OK_CHN = 1 # Parsed OK, control flow changed STATE_BROKEN_UTD = 2 # Parsed with errors, control flow up to date STATE_BROKEN_CHN = 3 # Parsed with errors, control flow changed STATE_UNKNOWN = 4 def __init__(self, parent): QFrame.__init__(self, parent) self.__infoIcon = None self.__warningsIcon = None self.__layout = None self.__pathLabel = None self.__createLayout() self.__currentIconState = self.STATE_UNKNOWN def __createLayout(self): """Creates the layout""" self.setFixedHeight(24) self.__layout = QHBoxLayout(self) self.__layout.setContentsMargins(0, 0, 0, 0) # Create info icon self.__infoIcon = QLabel(self) self.__infoIcon.setPixmap(getPixmap('cfunknown.png')) self.__layout.addWidget(self.__infoIcon) self.__warningsIcon = QLabel(self) self.__warningsIcon.setPixmap(getPixmap('cfwarning.png')) self.__layout.addWidget(self.__warningsIcon) self.clearWarnings() labelStylesheet = 'QLabel {' + getLabelStyle(self.__infoIcon) + '}' # Create the path label self.__pathLabel = QLabel(self) self.__pathLabel.setStyleSheet(labelStylesheet) self.__pathLabel.setTextFormat(Qt.PlainText) self.__pathLabel.setAlignment(Qt.AlignLeft) self.__pathLabel.setWordWrap(False) self.__pathLabel.setTextInteractionFlags(Qt.NoTextInteraction) self.__pathLabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.__layout.addWidget(self.__pathLabel) self.__spacer = QWidget() self.__spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.__spacer.setMinimumWidth(0) self.__layout.addWidget(self.__spacer) # Create the selection label self.__selectionLabel = QLabel(self) self.__selectionLabel.setStyleSheet(labelStylesheet) self.__selectionLabel.setTextFormat(Qt.PlainText) self.__selectionLabel.setAlignment(Qt.AlignCenter) self.__selectionLabel.setWordWrap(False) self.__selectionLabel.setTextInteractionFlags(Qt.NoTextInteraction) self.__selectionLabel.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.__selectionLabel.setMinimumWidth(40) self.__layout.addWidget(self.__selectionLabel) self.setSelectionLabel(0, None) def clearWarnings(self): """Clears the warnings""" self.__warningsIcon.setVisible(False) self.__warningsIcon.setToolTip("") def setWarnings(self, warnings): """Sets the warnings""" self.__warningsIcon.setToolTip('Control flow parser warnings:\n' + '\n'.join(warnings)) self.__warningsIcon.setVisible(True) def clearErrors(self): """Clears all the errors""" self.__infoIcon.setToolTip('') def setErrors(self, errors): """Sets the errors""" self.__infoIcon.setToolTip('Control flow parser errors:\n' + '\n'.join(errors)) def updateInfoIcon(self, state): """Updates the information icon""" if state == self.__currentIconState: return if state == self.STATE_OK_UTD: self.__infoIcon.setPixmap(getPixmap('cfokutd.png')) self.__infoIcon.setToolTip("Control flow is up to date") self.__currentIconState = self.STATE_OK_UTD elif state == self.STATE_OK_CHN: self.__infoIcon.setPixmap(getPixmap('cfokchn.png')) self.__infoIcon.setToolTip("Control flow is not up to date; " "will be updated on idle") self.__currentIconState = self.STATE_OK_CHN elif state == self.STATE_BROKEN_UTD: self.__infoIcon.setPixmap(getPixmap('cfbrokenutd.png')) self.__infoIcon.setToolTip("Control flow might be invalid " "due to invalid python code") self.__currentIconState = self.STATE_BROKEN_UTD elif state == self.STATE_BROKEN_CHN: self.__infoIcon.setPixmap(getPixmap('cfbrokenchn.png')) self.__infoIcon.setToolTip("Control flow might be invalid; " "will be updated on idle") self.__currentIconState = self.STATE_BROKEN_CHN else: # STATE_UNKNOWN self.__infoIcon.setPixmap(getPixmap('cfunknown.png')) self.__infoIcon.setToolTip("Control flow state is unknown") self.__currentIconState = self.STATE_UNKNOWN def getCurrentState(self): """Provides the current state""" return self.__currentIconState def setPath(self, txt): """Sets the path label content""" self.__pathLabel.setText(txt) def setPathVisible(self, switchOn): """Sets the path visible""" self.__pathLabel.setVisible(switchOn) self.__spacer.setVisible(not switchOn) def setSelectionLabel(self, text, tooltip): """Sets selection label""" self.__selectionLabel.setText(str(text)) if tooltip: self.__selectionLabel.setToolTip("Selected items:\n" + str(tooltip)) else: self.__selectionLabel.setToolTip("Number of selected items") def resizeEvent(self, event): """Editor has resized""" QFrame.resizeEvent(self, event)
class MDTopBar(QFrame): """MD widget top bar at the top""" STATE_OK_UTD = 0 # Parsed OK, MD up to date STATE_OK_CHN = 1 # Parsed OK, MD changed STATE_BROKEN_UTD = 2 # Parsed with errors, MD up to date STATE_BROKEN_CHN = 3 # Parsed with errors, MD changed STATE_UNKNOWN = 4 def __init__(self, parent): QFrame.__init__(self, parent) self.__infoIcon = None self.__warningsIcon = None self.__layout = None self.__createLayout() self.__currentIconState = self.STATE_UNKNOWN def __createLayout(self): """Creates the layout""" self.setFixedHeight(24) self.__layout = QHBoxLayout(self) self.__layout.setContentsMargins(0, 0, 0, 0) # Create info icon self.__infoIcon = QLabel() self.__infoIcon.setPixmap(getPixmap('cfunknown.png')) self.__layout.addWidget(self.__infoIcon) self.__warningsIcon = QLabel() self.__warningsIcon.setPixmap(getPixmap('cfwarning.png')) self.__layout.addWidget(self.__warningsIcon) self.clearWarnings() self.__spacer = QWidget() self.__spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.__spacer.setMinimumWidth(0) self.__layout.addWidget(self.__spacer) def clearWarnings(self): """Clears the warnings""" self.__warningsIcon.setVisible(False) self.__warningsIcon.setToolTip("") def setWarnings(self, warnings): """Sets the warnings""" self.__warningsIcon.setToolTip('Markdown parser warnings:\n' + '\n'.join(warnings)) self.__warningsIcon.setVisible(True) def clearErrors(self): """Clears all the errors""" self.__infoIcon.setToolTip('') def setErrors(self, errors): """Sets the errors""" self.__infoIcon.setToolTip('Markdown parser errors:\n' + '\n'.join(errors)) def updateInfoIcon(self, state): """Updates the information icon""" if state == self.__currentIconState: return if state == self.STATE_OK_UTD: self.__infoIcon.setPixmap(getPixmap('cfokutd.png')) self.__infoIcon.setToolTip("Markdown render is up to date") self.__currentIconState = self.STATE_OK_UTD elif state == self.STATE_OK_CHN: self.__infoIcon.setPixmap(getPixmap('cfokchn.png')) self.__infoIcon.setToolTip("Markdown render is not up to date; " "will be updated on idle") self.__currentIconState = self.STATE_OK_CHN elif state == self.STATE_BROKEN_UTD: self.__infoIcon.setPixmap(getPixmap('cfbrokenutd.png')) self.__infoIcon.setToolTip("Markdown render might be invalid " "due to invalid python code") self.__currentIconState = self.STATE_BROKEN_UTD elif state == self.STATE_BROKEN_CHN: self.__infoIcon.setPixmap(getPixmap('cfbrokenchn.png')) self.__infoIcon.setToolTip("Markdown render might be invalid; " "will be updated on idle") self.__currentIconState = self.STATE_BROKEN_CHN else: # STATE_UNKNOWN self.__infoIcon.setPixmap(getPixmap('cfunknown.png')) self.__infoIcon.setToolTip("Markdown render state is unknown") self.__currentIconState = self.STATE_UNKNOWN def getCurrentState(self): """Provides the current state""" return self.__currentIconState def resizeEvent(self, event): """Editor has resized""" QFrame.resizeEvent(self, event)
def __createLayout(self): """Creates the widget layout""" verticalLayout = QVBoxLayout(self) verticalLayout.setContentsMargins(0, 0, 0, 0) verticalLayout.setSpacing(0) self.__excptLabel = QLabel("Exceptions", self) self.headerFrame = QFrame() self.headerFrame.setObjectName('excpt') self.headerFrame.setStyleSheet('QFrame#excpt {' + getLabelStyle(self.__excptLabel) + '}') self.headerFrame.setFixedHeight(HEADER_HEIGHT) headerLayout = QHBoxLayout() headerLayout.setContentsMargins(0, 0, 0, 0) headerLayout.addSpacing(3) headerLayout.addWidget(self.__excptLabel) self.headerFrame.setLayout(headerLayout) self.exceptionsList = QTreeWidget(self) self.exceptionsList.setSortingEnabled(False) self.exceptionsList.setAlternatingRowColors(True) self.exceptionsList.setRootIsDecorated(True) self.exceptionsList.setItemsExpandable(True) self.exceptionsList.setUniformRowHeights(True) self.exceptionsList.setSelectionMode(QAbstractItemView.SingleSelection) self.exceptionsList.setSelectionBehavior(QAbstractItemView.SelectRows) self.exceptionsList.setItemDelegate(NoOutlineHeightDelegate(4)) self.exceptionsList.setContextMenuPolicy(Qt.CustomContextMenu) self.__addToIgnoreButton = QAction( getIcon('add.png'), "Add exception to the list of ignored", self) self.__addToIgnoreButton.triggered.connect(self.__onAddToIgnore) self.__addToIgnoreButton.setEnabled(False) expandingSpacer = QWidget() expandingSpacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.__jumpToCodeButton = QAction( getIcon('gotoline.png'), "Jump to the code", self) self.__jumpToCodeButton.triggered.connect(self.__onJumpToCode) self.__jumpToCodeButton.setEnabled(False) self.__delAllButton = QAction( getIcon('trash.png'), "Delete all the client exceptions", self) self.__delAllButton.triggered.connect(self.__onDelAll) self.__delAllButton.setEnabled(False) self.toolbar = QToolBar() self.toolbar.setOrientation(Qt.Horizontal) 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.__addToIgnoreButton) self.toolbar.addAction(self.__jumpToCodeButton) self.toolbar.addWidget(expandingSpacer) self.toolbar.addAction(self.__delAllButton) self.exceptionsList.itemDoubleClicked.connect( self.__onExceptionDoubleClicked) self.exceptionsList.customContextMenuRequested.connect( self.__showContextMenu) self.exceptionsList.itemSelectionChanged.connect( self.__onSelectionChanged) self.exceptionsList.setHeaderLabels(["Exception", "Function", "Arguments"]) verticalLayout.addWidget(self.headerFrame) verticalLayout.addWidget(self.toolbar) verticalLayout.addWidget(self.exceptionsList)
def __createLayout(self): """Creates the widget layout""" verticalLayout = QVBoxLayout(self) verticalLayout.setContentsMargins(0, 0, 0, 0) verticalLayout.setSpacing(0) self.__calltraceLabel = QLabel("Call Trace", self) self.headerFrame = QFrame() self.headerFrame.setObjectName('calltraceheader') self.headerFrame.setStyleSheet('QFrame#calltraceheader {' + getLabelStyle(self.__calltraceLabel) + '}') self.headerFrame.setFixedHeight(HEADER_HEIGHT) headerLayout = QHBoxLayout() headerLayout.setContentsMargins(0, 0, 0, 0) headerLayout.addSpacing(3) headerLayout.addWidget(self.__calltraceLabel) self.headerFrame.setLayout(headerLayout) self.calltraceList = CallTraceBrowser(self) self.__startButton = QAction(getIcon('calltracestart.png'), "Start call tracing", self) self.__startButton.triggered.connect(self.__onStart) self.__startButton.setEnabled(not Settings()['calltrace']) self.__stopButton = QAction(getIcon('calltracestop.png'), "Stop call tracing", self) self.__stopButton.triggered.connect(self.__onStop) self.__stopButton.setEnabled(Settings()['calltrace']) self.__resizeButton = QAction(getIcon('resizecolumns.png'), "Resize the columns to their contents", self) self.__resizeButton.triggered.connect(self.__onResize) self.__resizeButton.setEnabled(True) self.__clearButton = QAction(getIcon('trash.png'), "Clear", self) self.__clearButton.triggered.connect(self.__onClear) self.__clearButton.setEnabled(False) self.__copyButton = QAction(getIcon('copymenu.png'), "Copy to clipboard", self) self.__copyButton.triggered.connect(self.__onCopy) self.__copyButton.setEnabled(False) # Toolbar self.toolbar = QToolBar() self.toolbar.setOrientation(Qt.Horizontal) 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.__startButton) self.toolbar.addAction(self.__stopButton) fixedSpacer2 = QWidget() fixedSpacer2.setFixedWidth(15) self.toolbar.addWidget(fixedSpacer2) self.toolbar.addAction(self.__resizeButton) self.toolbar.addAction(self.__copyButton) expandingSpacer = QWidget() expandingSpacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) fixedSpacer4 = QWidget() fixedSpacer4.setFixedWidth(5) self.toolbar.addWidget(fixedSpacer4) self.toolbar.addWidget(expandingSpacer) self.toolbar.addAction(self.__clearButton) verticalLayout.addWidget(self.headerFrame) verticalLayout.addWidget(self.toolbar) verticalLayout.addWidget(self.calltraceList)
class NavigationBar(QFrame): """Navigation bar at the top of the editor (python only)""" STATE_OK_UTD = 0 # Parsed OK, context up to date STATE_OK_CHN = 1 # Parsed OK, context changed STATE_BROKEN_UTD = 2 # Parsed with errors, context up to date STATE_BROKEN_CHN = 3 # Parsed with errors, context changed STATE_UNKNOWN = 4 def __init__(self, editor, parent): QFrame.__init__(self, parent) self.__editor = editor self.__parentWidget = parent # It is always not visible at the beginning because there is no # editor content at the start self.setVisible(False) # There is no parser info used to display values self.__currentInfo = None self.__currentIconState = self.STATE_UNKNOWN self.__connected = False # List of PathElement starting after the global scope self.__path = [] self.__createLayout() # Create the update timer self.__updateTimer = QTimer(self) self.__updateTimer.setSingleShot(True) self.__updateTimer.timeout.connect(self.updateBar) # Connect to the change file type signal mainWindow = GlobalData().mainWindow editorsManager = mainWindow.editorsManagerWidget.editorsManager editorsManager.sigFileTypeChanged.connect(self.__onFileTypeChanged) def getEditor(self): """Provides the editor""" return self.__editor def __connectEditorSignals(self): """When it is a python file - connect to the editor signals""" if not self.__connected: self.__editor.cursorPositionChanged.connect( self.__cursorPositionChanged) self.__editor.textChanged.connect(self.__onBufferChanged) self.__connected = True def __disconnectEditorSignals(self): """Disconnect the editor signals when the file is not a python one""" if self.__connected: self.__editor.cursorPositionChanged.disconnect( self.__cursorPositionChanged) self.__editor.textChanged.disconnect(self.__onBufferChanged) self.__connected = False def __createLayout(self): """Creates the layout""" self.setFixedHeight(24) self.__layout = QHBoxLayout(self) self.__layout.setContentsMargins(0, 0, 0, 0) # Set the background color # Create info icon self.__infoIcon = QLabel() self.__layout.addWidget(self.__infoIcon) self.__globalScopeCombo = NavBarComboBox(self) self.__globalScopeCombo.jumpToLine.connect(self.__onJumpToLine) self.__layout.addWidget(self.__globalScopeCombo) self.__spacer = QWidget() self.__spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.__layout.addWidget(self.__spacer) def __updateInfoIcon(self, state): """Updates the information icon""" if state != self.__currentIconState: if state == self.STATE_OK_UTD: self.__infoIcon.setPixmap(getPixmap('nbokutd.png')) self.__infoIcon.setToolTip("Context is up to date") self.__currentIconState = self.STATE_OK_UTD elif state == self.STATE_OK_CHN: self.__infoIcon.setPixmap(getPixmap('nbokchn.png')) self.__infoIcon.setToolTip("Context is not up to date; " "will be updated on idle") self.__currentIconState = self.STATE_OK_CHN elif state == self.STATE_BROKEN_UTD: self.__infoIcon.setPixmap(getPixmap('nbbrokenutd.png')) self.__infoIcon.setToolTip("Context might be invalid " "due to invalid python code") self.__currentIconState = self.STATE_BROKEN_UTD else: # STATE_BROKEN_CHN self.__infoIcon.setPixmap(getPixmap('nbbrokenchn.png')) self.__infoIcon.setToolTip("Context might be invalid; " "will be updated on idle") self.__currentIconState = self.STATE_BROKEN_CHN def resizeEvent(self, event): """Editor has resized""" QFrame.resizeEvent(self, event) # Arguments: fileName, uuid, newFileType def __onFileTypeChanged(self, _, uuid, newFileType): """Triggered when a buffer content type has changed""" if self.__parentWidget.getUUID() != uuid: return if isPythonMime(newFileType) and Settings()['showNavigationBar']: # Update the bar and show it self.setVisible(True) self.updateBar() else: self.__disconnectEditorSignals() self.__updateTimer.stop() self.__currentInfo = None self.setVisible(False) self.__currentIconState = self.STATE_UNKNOWN def updateSettings(self): """Called when navigation bar settings have been updated""" textMime = self.__parentWidget.getMime() if Settings()['showNavigationBar'] and isPythonMime(textMime): self.setVisible(True) self.updateBar() else: self.__disconnectEditorSignals() self.__updateTimer.stop() self.__currentInfo = None self.setVisible(False) def updateBar(self): """Triggered when the timer is fired""" self.__updateTimer.stop() # just in case if not isPythonMime(self.__parentWidget.getMime()): return if not self.__connected: self.__connectEditorSignals() # Parse the buffer content self.__currentInfo = getBriefModuleInfoFromMemory(self.__editor.text) # Decide what icon to use if self.__currentInfo.isOK: self.__updateInfoIcon(self.STATE_OK_UTD) else: self.__updateInfoIcon(self.STATE_BROKEN_UTD) # Calc the cursor context context = getContext(self.__editor, self.__currentInfo, True, False) # Display the context self.__populateGlobalScope() if context.length == 0: self.__globalScopeCombo.setCurrentIndex(-1) else: index = self.__globalScopeCombo.findData( context.levels[0][0].line) self.__globalScopeCombo.setCurrentIndex(index) usedFromStore = 0 index = 1 while index < context.length: if len(self.__path) < index: newPathItem = PathElement(self) self.__path.append(newPathItem) self.__layout.addWidget(newPathItem.icon) self.__layout.addWidget(newPathItem.combo) combo = newPathItem.combo combo.pathIndex = len(self.__path) - 1 combo.jumpToLine.connect(self.__onJumpToLine) else: self.__path[index - 1].icon.setVisible(True) self.__path[index - 1].combo.setVisible(True) combo = self.__path[index - 1].combo combo.clear() # Populate the combo box self.__populateClassesAndFunctions(context.levels[index - 1][0], combo) combo.setCurrentIndex(combo.findData(context.levels[index][0].line)) index += 1 usedFromStore += 1 # it might need to have one more level with nothing selected if context.length > 0: if len(context.levels[context.length - 1][0].functions) > 0 or \ len(context.levels[context.length - 1][0].classes) > 0: # Need to add a combo if len(self.__path) <= usedFromStore: newPathItem = PathElement(self) self.__path.append(newPathItem) self.__layout.addWidget(newPathItem.icon) self.__layout.addWidget(newPathItem.combo) combo = newPathItem.combo combo.pathIndex = len(self.__path) - 1 combo.jumpToLine.connect(self.__onJumpToLine) else: self.__path[index - 1].icon.setVisible(True) self.__path[index - 1].combo.setVisible(True) combo = self.__path[index - 1].combo combo.clear() self.__populateClassesAndFunctions( context.levels[context.length - 1][0], combo) combo.setCurrentIndex(-1) usedFromStore += 1 # Hide extra components if so index = usedFromStore while index < len(self.__path): self.__path[index].icon.setVisible(False) self.__path[index].combo.setVisible(False) index += 1 # Make sure the spacer is the last item self.__layout.removeWidget(self.__spacer) self.__layout.addWidget(self.__spacer) def __populateGlobalScope(self): """Repopulates the global scope combo box""" self.__globalScopeCombo.clear() self.__populateClassesAndFunctions(self.__currentInfo, self.__globalScopeCombo) if not Settings()['navbarglobalsimports']: return if len(self.__currentInfo.globals) == 0 and \ len(self.__currentInfo.imports) == 0: return if self.__globalScopeCombo.count() != 0: self.__globalScopeCombo.insertSeparator( self.__globalScopeCombo.count()) for glob in self.__currentInfo.globals: self.__globalScopeCombo.addItem(getIcon('globalvar.png'), glob.name, glob.line) for imp in self.__currentInfo.imports: self.__globalScopeCombo.addItem(getIcon('imports.png'), imp.name, imp.line) @staticmethod def __populateClassesAndFunctions(infoObj, combo): """Populates the combo with classes and functions from the infoObj""" for klass in infoObj.classes: combo.addItem(getIcon('class.png'), klass.name, klass.line) for func in infoObj.functions: if func.isPrivate(): icon = getIcon('method_private.png') elif func.isProtected(): icon = getIcon('method_protected.png') else: icon = getIcon('method.png') combo.addItem(icon, func.name, func.line) def __cursorPositionChanged(self): """Cursor position changed""" self.__onNeedUpdate() def __onBufferChanged(self): """Buffer changed""" self.__onNeedUpdate() def __onNeedUpdate(self): """Triggered to update status icon and to restart the timer""" self.__updateTimer.stop() if self.__currentInfo.isOK: self.__updateInfoIcon(self.STATE_OK_CHN) else: self.__updateInfoIcon(self.STATE_BROKEN_CHN) self.__updateTimer.start(IDLE_TIMEOUT) def __onJumpToLine(self, line): """Triggered when it needs to jump to a line""" self.__editor.gotoLine(line, 0) self.__editor.setFocus() def setFocusToLastCombo(self): """Activates the last combo""" if self.__currentInfo is None: return for index in range(len(self.__path) - 1, -1, -1): if self.__path[index].combo.isVisible(): self.__path[index].combo.setFocus() self.__path[index].combo.showPopup() return self.__globalScopeCombo.setFocus() self.__globalScopeCombo.showPopup() def activateCombo(self, currentCombo, newIndex): """Triggered when a neighbour combo should be activated""" if newIndex == -1: if len(self.__path) > 0: if self.__path[0].combo.isVisible(): currentCombo.hidePopup() self.__globalScopeCombo.setFocus() self.__globalScopeCombo.showPopup() return if newIndex >= len(self.__path): # This is the most right one return if self.__path[newIndex].combo.isVisible(): currentCombo.hidePopup() self.__path[newIndex].combo.setFocus() self.__path[newIndex].combo.showPopup()
def __createLayout(self): """Creates the widget layout""" verticalLayout = QVBoxLayout(self) verticalLayout.setContentsMargins(0, 0, 0, 0) verticalLayout.setSpacing(0) self.__excptLabel = QLabel("Ignored exception types", self) self.headerFrame = QFrame() self.headerFrame.setObjectName('ignexcpt') self.headerFrame.setStyleSheet('QFrame#ignexcpt {' + getLabelStyle(self.__excptLabel) + '}') self.headerFrame.setFixedHeight(HEADER_HEIGHT) expandingSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding) self.__showHideButton = QToolButton() self.__showHideButton.setAutoRaise(True) self.__showHideButton.setIcon(getIcon('less.png')) self.__showHideButton.setFixedSize(HEADER_BUTTON, HEADER_BUTTON) self.__showHideButton.setToolTip("Hide ignored exceptions list") self.__showHideButton.setFocusPolicy(Qt.NoFocus) self.__showHideButton.clicked.connect(self.__onShowHide) headerLayout = QHBoxLayout() headerLayout.setContentsMargins(0, 0, 0, 0) headerLayout.addSpacing(3) headerLayout.addWidget(self.__excptLabel) headerLayout.addSpacerItem(expandingSpacer) headerLayout.addWidget(self.__showHideButton) self.headerFrame.setLayout(headerLayout) self.exceptionsList = QTreeWidget(self) self.exceptionsList.setSortingEnabled(False) self.exceptionsList.setAlternatingRowColors(True) self.exceptionsList.setRootIsDecorated(False) self.exceptionsList.setItemsExpandable(True) self.exceptionsList.setUniformRowHeights(True) self.exceptionsList.setSelectionMode(QAbstractItemView.SingleSelection) self.exceptionsList.setSelectionBehavior(QAbstractItemView.SelectRows) self.exceptionsList.setItemDelegate(NoOutlineHeightDelegate(4)) self.exceptionsList.setContextMenuPolicy(Qt.CustomContextMenu) self.exceptionsList.customContextMenuRequested.connect( self.__showContextMenu) self.exceptionsList.itemSelectionChanged.connect( self.__onSelectionChanged) self.exceptionsList.setHeaderLabels(["Exception type"]) self.__excTypeEdit = QLineEdit() self.__excTypeEdit.setFixedHeight(26) self.__excTypeEdit.textChanged.connect(self.__onNewFilterChanged) self.__excTypeEdit.returnPressed.connect(self.__onAddExceptionFilter) self.__addButton = QPushButton("Add") # self.__addButton.setFocusPolicy(Qt.NoFocus) self.__addButton.setEnabled(False) self.__addButton.clicked.connect(self.__onAddExceptionFilter) expandingSpacer2 = QWidget() expandingSpacer2.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.__removeButton = QAction(getIcon('delitem.png'), "Remove selected exception type", self) self.__removeButton.triggered.connect(self.__onRemoveFromIgnore) self.__removeButton.setEnabled(False) fixedSpacer1 = QWidget() fixedSpacer1.setFixedWidth(5) self.__removeAllButton = QAction(getIcon('ignexcptdelall.png'), "Remove all the exception types", self) self.__removeAllButton.triggered.connect(self.__onRemoveAllFromIgnore) self.__removeAllButton.setEnabled(False) self.toolbar = QToolBar() self.toolbar.setOrientation(Qt.Horizontal) 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.addWidget(expandingSpacer2) self.toolbar.addAction(self.__removeButton) self.toolbar.addWidget(fixedSpacer1) self.toolbar.addAction(self.__removeAllButton) addLayout = QHBoxLayout() addLayout.setContentsMargins(1, 1, 1, 1) addLayout.setSpacing(1) addLayout.addWidget(self.__excTypeEdit) addLayout.addWidget(self.__addButton) verticalLayout.addWidget(self.headerFrame) verticalLayout.addWidget(self.toolbar) verticalLayout.addWidget(self.exceptionsList) verticalLayout.addLayout(addLayout)
def __createLayout(self): """Creates the toolbar and layout""" self.__settingsMenu = QMenu(self) self.__settingsMenu.aboutToShow.connect(self.__settingsAboutToShow) self.__wrapLongLinesAct = self.__settingsMenu.addAction( "Wrap long lines") self.__wrapLongLinesAct.setCheckable(True) self.__wrapLongLinesAct.triggered.connect(self.__onWrapLongLines) self.__showWhitespacesAct = self.__settingsMenu.addAction( "Show whitespaces") self.__showWhitespacesAct.setCheckable(True) self.__showWhitespacesAct.triggered.connect(self.__onShowWhitespaces) self.__autoscrollAct = self.__settingsMenu.addAction("Autoscroll") self.__autoscrollAct.setCheckable(True) self.__autoscrollAct.triggered.connect(self.__onAutoscroll) self.__settingsButton = QToolButton(self) self.__settingsButton.setIcon(getIcon('iosettings.png')) self.__settingsButton.setToolTip('View settings') self.__settingsButton.setPopupMode(QToolButton.InstantPopup) self.__settingsButton.setMenu(self.__settingsMenu) self.__settingsButton.setFocusPolicy(Qt.NoFocus) if self.kind != DEBUG: fixedSpacer = QWidget() fixedSpacer.setFixedHeight(8) self.__stopButton = QAction(getIcon('runconsolestop.png'), 'Stop process', self) self.__stopButton.triggered.connect(self.stop) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.__clearButton = QAction(getIcon('trash.png'), 'Clear', self) self.__clearButton.triggered.connect(self.clear) # The 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.addWidget(self.__settingsButton) if self.kind != DEBUG: toolbar.addWidget(fixedSpacer) toolbar.addAction(self.__stopButton) toolbar.addWidget(spacer) toolbar.addAction(self.__clearButton) hLayout = QHBoxLayout() hLayout.setContentsMargins(0, 0, 0, 0) hLayout.setSpacing(0) hLayout.addWidget(toolbar) hLayout.addWidget(self.__viewer) self.setLayout(hLayout)