def __init__(self, editor, parent): QWidget.__init__(self, parent) # It is always not visible at the beginning because there is no # editor content at the start self.setVisible(False) self.__editor = editor self.__parentWidget = parent self.__connected = False self.__needPathUpdate = False self.cflowSettings = getCflowSettings(self) self.__displayProps = (self.cflowSettings.hidedocstrings, self.cflowSettings.hidecomments, self.cflowSettings.hideexcepts, Settings()['smartZoom']) hLayout = QHBoxLayout() hLayout.setContentsMargins(0, 0, 0, 0) hLayout.setSpacing(0) vLayout = QVBoxLayout() vLayout.setContentsMargins(0, 0, 0, 0) vLayout.setSpacing(0) # Make pylint happy self.__toolbar = None self.__navBar = None self.__cf = None self.__canvas = None self.__validGroups = [] self.__allGroupId = set() # Create the update timer self.__updateTimer = QTimer(self) self.__updateTimer.setSingleShot(True) self.__updateTimer.timeout.connect(self.process) vLayout.addWidget(self.__createNavigationBar()) vLayout.addWidget(self.__createStackedViews()) hLayout.addLayout(vLayout) hLayout.addWidget(self.__createToolbar()) self.setLayout(hLayout) self.updateSettings() # Connect to the change file type signal self.__mainWindow = GlobalData().mainWindow editorsManager = self.__mainWindow.editorsManagerWidget.editorsManager editorsManager.sigFileTypeChanged.connect(self.__onFileTypeChanged) Settings().sigHideDocstringsChanged.connect( self.__onHideDocstringsChanged) Settings().sigHideCommentsChanged.connect(self.__onHideCommentsChanged) Settings().sigHideExceptsChanged.connect(self.__onHideExceptsChanged) Settings().sigSmartZoomChanged.connect(self.__onSmartZoomChanged) self.setSmartZoomLevel(Settings()['smartZoom'])
def __createLayout(self): """Creates the widget layout""" verticalLayout = QVBoxLayout(self) verticalLayout.setContentsMargins(0, 0, 0, 0) verticalLayout.setSpacing(0) self.headerFrame = QFrame() self.headerFrame.setObjectName('stackheader') self.headerFrame.setStyleSheet('QFrame#stackheader {' + getLabelStyle(self) + '}') self.headerFrame.setFixedHeight(HEADER_HEIGHT) self.__stackLabel = QLabel("Stack") 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 frames 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.__stackLabel) headerLayout.addSpacerItem(expandingSpacer) headerLayout.addWidget(self.__showHideButton) self.headerFrame.setLayout(headerLayout) self.__framesList = QTreeWidget(self) self.__framesList.setSortingEnabled(False) # I might not need that because of two reasons: # - the window has no focus # - the window has custom current indicator # self.__framesList.setAlternatingRowColors(True) self.__framesList.setRootIsDecorated(False) self.__framesList.setItemsExpandable(False) self.__framesList.setUniformRowHeights(True) self.__framesList.setSelectionMode(QAbstractItemView.NoSelection) self.__framesList.setSelectionBehavior(QAbstractItemView.SelectRows) self.__framesList.setItemDelegate(NoOutlineHeightDelegate(4)) self.__framesList.setFocusPolicy(Qt.NoFocus) self.__framesList.setContextMenuPolicy(Qt.CustomContextMenu) self.__framesList.itemClicked.connect(self.__onFrameClicked) self.__framesList.itemDoubleClicked.connect( self.__onFrameDoubleClicked) self.__framesList.customContextMenuRequested.connect( self.__showContextMenu) self.__framesList.setHeaderLabels( ["", "File:line", "Function", "Arguments", "Full path"]) verticalLayout.addWidget(self.headerFrame) verticalLayout.addWidget(self.__framesList)
def __createLayout(self): """Creates the toolbar and layout""" # Buttons printButton = QAction(getIcon('printer.png'), 'Print', self) # printButton.setShortcut('Ctrl+') printButton.triggered.connect(self.__onPrint) printPreviewButton = QAction(getIcon('printpreview.png'), 'Print preview', self) # printPreviewButton.setShortcut('Ctrl+') printPreviewButton.triggered.connect(self.__onPrintPreview) fixedSpacer = QWidget() fixedSpacer.setFixedHeight(16) zoomInButton = QAction(getIcon('zoomin.png'), 'Zoom in (Ctrl+=)', self) zoomInButton.setShortcut('Ctrl+=') zoomInButton.triggered.connect(self.onZoomIn) zoomOutButton = QAction(getIcon('zoomout.png'), 'Zoom out (Ctrl+-)', self) zoomOutButton.setShortcut('Ctrl+-') zoomOutButton.triggered.connect(self.onZoomOut) zoomResetButton = QAction(getIcon('zoomreset.png'), 'Zoom reset (Ctrl+0)', self) zoomResetButton.setShortcut('Ctrl+0') zoomResetButton.triggered.connect(self.onZoomReset) # 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(fixedSpacer) toolbar.addAction(zoomInButton) toolbar.addAction(zoomOutButton) toolbar.addAction(zoomResetButton) hLayout = QHBoxLayout() hLayout.setContentsMargins(0, 0, 0, 0) hLayout.setSpacing(0) hLayout.addWidget(self.__viewer) hLayout.addWidget(toolbar) self.setLayout(hLayout)
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 __init__(self, editor, parent): QWidget.__init__(self, parent) self.setVisible(False) self.__editor = editor self.__parentWidget = parent self.__connected = False hLayout = QHBoxLayout() hLayout.setContentsMargins(0, 0, 0, 0) hLayout.setSpacing(0) vLayout = QVBoxLayout() vLayout.setContentsMargins(0, 0, 0, 0) vLayout.setSpacing(0) # Make pylint happy self.__toolbar = None self.__topBar = None # Create the update timer self.__updateTimer = QTimer(self) self.__updateTimer.setSingleShot(True) self.__updateTimer.timeout.connect(self.process) vLayout.addWidget(self.__createTopBar()) vLayout.addWidget(self.__createMDView()) hLayout.addLayout(vLayout) hLayout.addWidget(self.__createToolbar()) self.setLayout(hLayout) # Connect to the change file type signal self.__mainWindow = GlobalData().mainWindow editorsManager = self.__mainWindow.editorsManagerWidget.editorsManager editorsManager.sigFileTypeChanged.connect(self.__onFileTypeChanged)
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 toolbar and layout""" # Buttons self.__toggleViewButton = QAction(getIcon('tableview.png'), 'Switch to table view', self) self.__toggleViewButton.setCheckable(True) self.__toggleViewButton.toggled.connect(self.__switchView) self.__togglePathButton = QAction(getIcon('longpath.png'), 'Show full paths for item location', self) self.__togglePathButton.setCheckable(True) self.__togglePathButton.toggled.connect(self.__togglePath) self.__togglePathButton.setEnabled(False) self.__printButton = QAction(getIcon('printer.png'), 'Print', self) self.__printButton.triggered.connect(self.__onPrint) self.__printButton.setEnabled(False) self.__printPreviewButton = QAction(getIcon('printpreview.png'), 'Print preview', self) self.__printPreviewButton.triggered.connect(self.__onPrintPreview) self.__printPreviewButton.setEnabled(False) fixedSpacer = QWidget() fixedSpacer.setFixedHeight(16) self.__zoomInButton = QAction(getIcon('zoomin.png'), 'Zoom in (Ctrl+=)', self) self.__zoomInButton.setShortcut('Ctrl+=') self.__zoomInButton.triggered.connect(self.onZoomIn) self.__zoomOutButton = QAction(getIcon('zoomout.png'), 'Zoom out (Ctrl+-)', self) self.__zoomOutButton.setShortcut('Ctrl+-') self.__zoomOutButton.triggered.connect(self.onZoomOut) self.__zoomResetButton = QAction(getIcon('zoomreset.png'), 'Zoom reset (Ctrl+0)', self) self.__zoomResetButton.setShortcut('Ctrl+0') self.__zoomResetButton.triggered.connect(self.onZoomReset) # 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.__toggleViewButton) toolbar.addAction(self.__togglePathButton) toolbar.addAction(self.__printPreviewButton) toolbar.addAction(self.__printButton) toolbar.addWidget(fixedSpacer) toolbar.addAction(self.__zoomInButton) toolbar.addAction(self.__zoomOutButton) toolbar.addAction(self.__zoomResetButton) hLayout = QHBoxLayout() hLayout.setContentsMargins(0, 0, 0, 0) hLayout.setSpacing(0) hLayout.addWidget(self.__profTable) hLayout.addWidget(self.__profGraph) hLayout.addWidget(toolbar) self.setLayout(hLayout)
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) headerFrame = QFrame() headerFrame.setObjectName('varsheader') headerFrame.setStyleSheet('QFrame#varsheader {' + getLabelStyle(self) + '}') headerFrame.setFixedHeight(HEADER_HEIGHT) self.__headerLabel = QLabel("Variables") expandingSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding) self.__filterMenu = QMenu(self) self.__showAllAct = self.__filterMenu.addAction('Show all variables') self.__showAllAct.setData('showall') self.__filterMenu.addSeparator() self.__filters = [] for title, settingName, _ in VARIABLE_FILTERS: action = self.__filterMenu.addAction(title) action.setCheckable(True) action.setData(settingName) self.__filters.append(action) self.__filterMenu.aboutToShow.connect(self.__filterMenuAboutToShow) self.__filterMenu.triggered.connect(self.__filterMenuTriggered) self.__filterButton = QToolButton(self) self.__filterButton.setIcon(getIcon('dbgvarflt.png')) self.__filterButton.setToolTip('Variable filter') self.__filterButton.setPopupMode(QToolButton.InstantPopup) self.__filterButton.setMenu(self.__filterMenu) self.__filterButton.setFocusPolicy(Qt.NoFocus) self.__filterButton.setFixedSize(HEADER_BUTTON, HEADER_BUTTON) self.__execStatement = CDMComboBox(True) self.__execStatement.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.__execStatement.lineEdit().setToolTip("Execute statement") self.__execStatement.setFixedHeight(26) self.__execStatement.editTextChanged.connect( self.__execStatementChanged) self.__execStatement.enterClicked.connect(self.__onEnterInExec) self.__execButton = QPushButton("Exec") self.__execButton.setEnabled(False) self.__execButton.setFixedHeight(26) self.__execButton.clicked.connect(self.__onExec) headerLayout = QHBoxLayout() headerLayout.setContentsMargins(0, 0, 0, 0) headerLayout.setSpacing(0) headerLayout.addSpacing(3) headerLayout.addWidget(self.__headerLabel) headerLayout.addSpacerItem(expandingSpacer) headerLayout.addWidget(self.__filterButton) headerFrame.setLayout(headerLayout) execLayout = QGridLayout() execLayout.setContentsMargins(1, 1, 1, 1) execLayout.setSpacing(1) execLayout.addWidget(self.__execStatement, 0, 0) execLayout.addWidget(self.__execButton, 0, 1) verticalLayout.addWidget(headerFrame) verticalLayout.addWidget(self.__browser) verticalLayout.addLayout(execLayout)
def __createLayout(self): """Creates the widget layout""" verticalLayout = QVBoxLayout(self) verticalLayout.setContentsMargins(0, 0, 0, 0) verticalLayout.setSpacing(0) self.__excptLabel = HeaderFitLabel(self) self.__excptLabel.setText('Ignored exception types') self.__excptLabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.__excptLabel.setMinimumWidth(10) self.__showHideButton = QToolButton() self.__showHideButton.setAutoRaise(True) self.__showHideButton.setIcon(getIcon('less.png')) self.__showHideButton.setFixedSize(self.__excptLabel.height(), self.__excptLabel.height()) self.__showHideButton.setToolTip('Hide ignored exceptions list') self.__showHideButton.setFocusPolicy(Qt.NoFocus) self.__showHideButton.clicked.connect(self.onShowHide) self.headerToolbar = QToolBar(self) self.headerToolbar.setIconSize(QSize(16, 16)) self.headerToolbar.setContentsMargins(1, 1, 1, 1) self.headerToolbar.addWidget(self.__excptLabel) self.headerToolbar.addWidget(self.__showHideButton) 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) self.__removeButton = QAction(getIcon('delitem.png'), "Remove selected exception type", self) self.__removeButton.triggered.connect(self.__onRemoveFromIgnore) self.__removeButton.setEnabled(False) 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(ToolBarExpandingSpacer(self.toolbar)) self.toolbar.addAction(self.__removeButton) self.toolbar.addWidget(ToolBarHSpacer(self.toolbar, 5)) 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.headerToolbar) verticalLayout.addWidget(self.toolbar) verticalLayout.addWidget(self.exceptionsList) verticalLayout.addLayout(addLayout)
def __createLayout(self, wpointModel): """Creates the widget layout""" verticalLayout = QVBoxLayout(self) verticalLayout.setContentsMargins(0, 0, 0, 0) verticalLayout.setSpacing(0) self.headerFrame = QFrame() self.headerFrame.setFrameStyle(QFrame.StyledPanel) self.headerFrame.setAutoFillBackground(True) headerPalette = self.headerFrame.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.headerFrame.setPalette(headerPalette) self.headerFrame.setFixedHeight(24) self.__watchpointLabel = QLabel("Watchpoints") expandingSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding) fixedSpacer = QSpacerItem(3, 3) self.__showHideButton = QToolButton() self.__showHideButton.setAutoRaise(True) self.__showHideButton.setIcon(getIcon('less.png')) self.__showHideButton.setFixedSize(20, 20) self.__showHideButton.setToolTip("Hide ignored exceptions list") self.__showHideButton.setFocusPolicy(Qt.NoFocus) self.__showHideButton.clicked.connect(self.__onShowHide) headerLayout = QHBoxLayout() headerLayout.setContentsMargins(1, 1, 1, 1) headerLayout.addSpacerItem(fixedSpacer) headerLayout.addWidget(self.__watchpointLabel) headerLayout.addSpacerItem(expandingSpacer) headerLayout.addWidget(self.__showHideButton) self.headerFrame.setLayout(headerLayout) self.__wpointsList = WatchPointView(self, wpointModel) self.__enableButton = QToolButton() self.__enableButton.setIcon(getIcon('add.png')) self.__enableButton.setFixedSize(24, 24) self.__enableButton.setToolTip("Enable/disable the watchpoint") self.__enableButton.setFocusPolicy(Qt.NoFocus) self.__enableButton.setEnabled(False) self.__enableButton.clicked.connect(self.__onEnableDisable) expandingSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding) self.__jumpToCodeButton = QToolButton() self.__jumpToCodeButton.setIcon(getIcon('gotoline.png')) self.__jumpToCodeButton.setFixedSize(24, 24) self.__jumpToCodeButton.setToolTip("Jump to the code") self.__jumpToCodeButton.setFocusPolicy(Qt.NoFocus) self.__jumpToCodeButton.setEnabled(False) self.__jumpToCodeButton.clicked.connect(self.__onJumpToCode) toolbarLayout = QHBoxLayout() toolbarLayout.addWidget(self.__enableButton) toolbarLayout.addSpacerItem(expandingSpacer) toolbarLayout.addWidget(self.__jumpToCodeButton) self.__wpointsList.sigSelectionChanged.connect( self.__onSelectionChanged) verticalLayout.addWidget(self.headerFrame) verticalLayout.addLayout(toolbarLayout) verticalLayout.addWidget(self.__wpointsList)
class PylintResultViewer(QWidget): """Pylint results viewer""" def __init__(self, ide, pluginHomeDir, parent=None): QWidget.__init__(self, parent) self.__results = None self.__ide = ide self.__pluginHomeDir = pluginHomeDir self.__noneLabel = QLabel("\nNo results available") self.__noneLabel.setFrameShape(QFrame.StyledPanel) self.__noneLabel.setAlignment(Qt.AlignHCenter) font = self.__noneLabel.font() font.setPointSize(font.pointSize() + 4) self.__noneLabel.setFont(font) self.__noneLabel.setAutoFillBackground(True) noneLabelPalette = self.__noneLabel.palette() noneLabelPalette.setColor(QPalette.Background, GlobalData().skin['nolexerPaper']) self.__noneLabel.setPalette(noneLabelPalette) self.__createLayout(self.__pluginHomeDir) def __createLayout(self, pluginHomeDir): """Creates the layout""" self.clearButton = QAction(getIcon('trash.png'), 'Clear', self) self.clearButton.triggered.connect(self.clear) self.outputButton = QAction(QIcon(pluginHomeDir + 'output.png'), 'Show pylint raw stdout and stderr', self) self.outputButton.triggered.connect(self.__showOutput) 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.outputButton) self.toolbar.addWidget(ToolBarExpandingSpacer(self.toolbar)) self.toolbar.addAction(self.clearButton) self.__resultsTree = QTreeWidget(self) self.__resultsTree.setAlternatingRowColors(True) self.__resultsTree.setRootIsDecorated(True) self.__resultsTree.setItemsExpandable(True) self.__resultsTree.setUniformRowHeights(True) self.__resultsTree.setItemDelegate(NoOutlineHeightDelegate(4)) headerLabels = ['Message type / line', 'id', 'Message'] self.__resultsTree.setHeaderLabels(headerLabels) self.__resultsTree.itemActivated.connect(self.__resultActivated) self.__fileLabel = HeaderFitPathLabel(None, self) self.__fileLabel.setAlignment(Qt.AlignLeft) self.__fileLabel.setMinimumWidth(50) self.__fileLabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.__fileLabel.doubleClicked.connect(self.onPathLabelDoubleClick) self.__fileLabel.setContextMenuPolicy(Qt.CustomContextMenu) self.__fileLabel.customContextMenuRequested.connect( self.showPathLabelContextMenu) self.__rateLabel = HeaderLabel() self.__rateLabel.setToolTip('pylint analysis rate out of 10 ' '(previous run if there was one)') self.__timestampLabel = HeaderLabel() self.__timestampLabel.setToolTip('pylint analysis timestamp') self.__labelLayout = QHBoxLayout() self.__labelLayout.setSpacing(4) self.__labelLayout.addWidget(self.__fileLabel) self.__labelLayout.addWidget(self.__rateLabel) self.__labelLayout.addWidget(self.__timestampLabel) self.__vLayout = QVBoxLayout() self.__vLayout.setSpacing(4) self.__vLayout.addLayout(self.__labelLayout) self.__vLayout.addWidget(self.__resultsTree) 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.addLayout(self.__vLayout) self.setLayout(self.__hLayout) self.__updateButtons() def __updateButtons(self): """Updates the toolbar buttons approprietly""" self.clearButton.setEnabled(self.__results is not None) if self.__results is not None: stdout = self.__results.get('StdOut', None) stderr = self.__results.get('StdErr', None) self.outputButton.setEnabled(stdout is not None or stderr is not None) else: self.outputButton.setEnabled(False) def showResults(self, results): """Populates the analysis results""" self.clear() self.__noneLabel.setVisible(False) self.__fileLabel.setVisible(True) self.__rateLabel.setVisible(True) self.__timestampLabel.setVisible(True) self.__resultsTree.setVisible(True) self.__results = results self.__updateButtons() tooltip = ' '.join(['pylint results for', os.path.basename(results['FileName']), 'at', results['Timestamp']]) self.__ide.sideBars['bottom'].setTabToolTip('pylint', tooltip) self.__fileLabel.setPath(results['FileName']) if 'Rate' in results: text = str(results['Rate']) if 'PreviousRunRate' in results: text += ' (' + str(results['PreviousRunRate']) + ')' self.__rateLabel.setText(' ' + text + ' ') else: self.__rateLabel.setVisible(False) self.__timestampLabel.setText(results['Timestamp']) totalMessages = 0 totalMessages += self.__populateMessages('Errors') totalMessages += self.__populateMessages('Warnings') totalMessages += self.__populateMessages('Refactoring') totalMessages += self.__populateMessages('Cosmetics') # Update the header with the total number of matches headerLabels = ['Message type / line', 'id', 'Message (total messages: ' + str(totalMessages) + ')'] self.__resultsTree.setHeaderLabels(headerLabels) # Resizing self.__resultsTree.header().resizeSections( QHeaderView.ResizeToContents) def __populateMessages(self, title): """Populates the analysis messages""" count = len(self.__results[title[0]]) if count > 0: suffix = '' if count == 1 else 's' messageTypeItem = MessageTypeTableItem( [title, '', '(' + str(count) + ' message' + suffix + ')']) self.__resultsTree.addTopLevelItem(messageTypeItem) for item in self.__results[title[0]]: columns = [str(item[1]), item[3], item[2]] messageItem = MessageTableItem(columns) messageTypeItem.addChild(messageItem) messageTypeItem.setExpanded(True) return count def clear(self): """Clears the results view""" self.__results = None self.__updateButtons() tooltip = 'No results available' self.__ide.sideBars['bottom'].setTabToolTip('pylint', tooltip) self.__noneLabel.setVisible(True) self.__fileLabel.setVisible(False) self.__rateLabel.setVisible(False) self.__timestampLabel.setVisible(False) self.__resultsTree.setVisible(False) self.__resultsTree.clear() def __resultActivated(self, item, column): """Handles the double click (or Enter) on a message""" del column # unused argument if self.__results: if isinstance(item, MessageTableItem): fileName = self.__results['FileName'] lineNumber = int(item.data(0, Qt.DisplayRole)) self.__ide.mainWindow.openFile(fileName, lineNumber) def __showOutput(self): """Shows the analysis stdout and stderr""" if self.__results is None: return # Show a separate dialog PylintStdoutStderrViewer(self.__ide.mainWindow, self.__results).exec_() def onPathLabelDoubleClick(self): """Double click on the path label""" txt = self.__getPathLabelFilePath() if txt.lower(): QApplication.clipboard().setText(txt) def __getPathLabelFilePath(self): """Provides undecorated path label content""" txt = str(self.__fileLabel.getPath()) if txt.startswith('File: '): return txt.replace('File: ', '') return txt def showPathLabelContextMenu(self, pos): """Triggered when a context menu is requested for the path label""" contextMenu = QMenu(self) contextMenu.addAction(getIcon('copymenu.png'), 'Copy full path to clipboard (double click)', self.onPathLabelDoubleClick) contextMenu.addSeparator() contextMenu.addAction(getIcon(''), 'Copy directory path to clipboard', self.onCopyDirToClipboard) contextMenu.addAction(getIcon(''), 'Copy file name to clipboard', self.onCopyFileNameToClipboard) contextMenu.popup(self.__fileLabel.mapToGlobal(pos)) def onCopyDirToClipboard(self): """Copies the dir path of the current file into the clipboard""" txt = self.__getPathLabelFilePath() if txt.lower(): try: QApplication.clipboard().setText(os.path.dirname(txt) + os.path.sep) except: pass def onCopyFileNameToClipboard(self): """Copies the file name of the current file into the clipboard""" txt = self.__getPathLabelFilePath() if txt.lower(): try: QApplication.clipboard().setText(os.path.basename(txt)) except: pass
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, pathsToCommit, pathsToIgnore): """Creates the dialog layout""" self.resize(640, 480) self.setSizeGripEnabled(True) vboxLayout = QVBoxLayout(self) # Paths to commit part commitHeaderFrame = QFrame() commitHeaderFrame.setFrameStyle(QFrame.StyledPanel) commitHeaderFrame.setAutoFillBackground(True) self.__setLightPalette(commitHeaderFrame) commitHeaderFrame.setFixedHeight(24) expandingCommitSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding) self.__selectAllButton = QToolButton() self.__selectAllButton.setAutoRaise(True) self.__selectAllButton.setIcon( getIcon(pluginHomeDir + 'svnselectall.png')) self.__selectAllButton.setFixedSize(20, 20) self.__selectAllButton.setToolTip("Select all") self.__selectAllButton.setFocusPolicy(Qt.NoFocus) self.__selectAllButton.clicked.connect(self.__onSelectAll) commitHeaderLayout = QHBoxLayout() commitHeaderLayout.setContentsMargins(3, 0, 0, 0) commitHeaderLayout.addWidget( QLabel("Paths to commit (total: " + str(len(pathsToCommit)) + ")")) commitHeaderLayout.addSpacerItem(expandingCommitSpacer) commitHeaderLayout.addWidget(self.__selectAllButton) commitHeaderFrame.setLayout(commitHeaderLayout) vboxLayout.addWidget(commitHeaderFrame) self.__pathToCommitView = QTreeWidget() self.__configTable(self.__pathToCommitView) self.__pathToCommitHeader = QTreeWidgetItem(["", "Path", "Status", ""]) self.__pathToCommitView.setHeaderItem(self.__pathToCommitHeader) self.__pathToCommitView.header().setSortIndicator( PATH_COL, Qt.AscendingOrder) self.__pathToCommitView.itemChanged.connect(self.__onCommitPathChanged) vboxLayout.addWidget(self.__pathToCommitView) # Paths to ignore part headerFrame = QFrame() headerFrame.setFrameStyle(QFrame.StyledPanel) headerFrame.setAutoFillBackground(True) self.__setLightPalette(headerFrame) headerFrame.setFixedHeight(24) ignoreLabel = QLabel("Ignored paths (total: " + str(len(pathsToIgnore)) + ")") expandingSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding) self.__showHideIgnoredButton = QToolButton() self.__showHideIgnoredButton.setAutoRaise(True) self.__showHideIgnoredButton.setIcon(getIcon('less.png')) self.__showHideIgnoredButton.setFixedSize(20, 20) self.__showHideIgnoredButton.setToolTip("Show ignored path list") self.__showHideIgnoredButton.setFocusPolicy(Qt.NoFocus) self.__showHideIgnoredButton.clicked.connect(self.__onShowHideIgnored) ignoredHeaderLayout = QHBoxLayout() ignoredHeaderLayout.setContentsMargins(3, 0, 0, 0) ignoredHeaderLayout.addWidget(ignoreLabel) ignoredHeaderLayout.addSpacerItem(expandingSpacer) ignoredHeaderLayout.addWidget(self.__showHideIgnoredButton) headerFrame.setLayout(ignoredHeaderLayout) vboxLayout.addWidget(headerFrame) self.__pathToIgnoreView = QTreeWidget() self.__configTable(self.__pathToIgnoreView) self.__pathToIgnoreView.setVisible(False) pathToIgnoreHeader = QTreeWidgetItem(["Path", "Status"]) self.__pathToIgnoreView.setHeaderItem(pathToIgnoreHeader) self.__pathToIgnoreView.header().setSortIndicator(0, Qt.AscendingOrder) vboxLayout.addWidget(self.__pathToIgnoreView) # Message part vboxLayout.addWidget(QLabel("Message")) self.__message = QTextEdit() self.__message.setAcceptRichText(False) metrics = QFontMetrics(self.__message.font()) rect = metrics.boundingRect("X") self.__message.setFixedHeight(rect.height() * 4 + 5) vboxLayout.addWidget(self.__message) # Diff part diffHeaderFrame = QFrame() diffHeaderFrame.setFrameStyle(QFrame.StyledPanel) diffHeaderFrame.setAutoFillBackground(True) self.__setLightPalette(diffHeaderFrame) diffHeaderFrame.setFixedHeight(24) diffLabel = QLabel("Diff") diffExpandingSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding) self.__showHideDiffButton = QToolButton() self.__showHideDiffButton.setAutoRaise(True) self.__showHideDiffButton.setIcon(getIcon('less.png')) self.__showHideDiffButton.setFixedSize(20, 20) self.__showHideDiffButton.setToolTip("Show diff") self.__showHideDiffButton.setFocusPolicy(Qt.NoFocus) self.__showHideDiffButton.clicked.connect(self.__onShowHideDiff) diffLayout = QHBoxLayout() diffLayout.setContentsMargins(3, 0, 0, 0) diffLayout.addWidget(diffLabel) diffLayout.addSpacerItem(diffExpandingSpacer) diffLayout.addWidget(self.__showHideDiffButton) diffHeaderFrame.setLayout(diffLayout) self.__diffViewer = DiffTabWidget() self.__diffViewer.setHTML(self.NODIFF) self.__diffViewer.setVisible(False) vboxLayout.addWidget(diffHeaderFrame) vboxLayout.addWidget(self.__diffViewer) # Buttons at the bottom buttonBox = QDialogButtonBox(self) buttonBox.setOrientation(Qt.Horizontal) buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.__OKButton = buttonBox.button(QDialogButtonBox.Ok) self.__OKButton.setText("Commit") buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) buttonBox.accepted.connect(self.userAccept) buttonBox.rejected.connect(self.close) vboxLayout.addWidget(buttonBox)
def __createLayout(self): """Creates the dialog layout""" self.resize(640, 480) self.setSizeGripEnabled(True) vboxLayout = QVBoxLayout(self) # Revisions to compare compareGroupbox = QGroupBox(self) compareGroupbox.setTitle("Revisions to compare") sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( compareGroupbox.sizePolicy().hasHeightForWidth()) compareGroupbox.setSizePolicy(sizePolicy) revisionLayout = QHBoxLayout(compareGroupbox) self.__lhsRevisionLabel = QLabel() self.__lhsRevisionLabel.setFrameStyle(QFrame.StyledPanel) self.__lhsResetButton = QToolButton() self.__lhsResetButton.setIcon( getIcon(pluginHomeDir + 'svnclearrev.png')) self.__lhsResetButton.setFocusPolicy(Qt.NoFocus) self.__lhsResetButton.setEnabled(False) self.__lhsResetButton.setToolTip("Reset revision to compare") self.__lhsResetButton.clicked.connect(self.__onLHSReset) self.__rhsRevisionLabel = QLabel() self.__rhsRevisionLabel.setFrameStyle(QFrame.StyledPanel) self.__rhsResetButton = QToolButton() self.__rhsResetButton.setIcon( getIcon(pluginHomeDir + 'svnclearrev.png')) self.__rhsResetButton.setFocusPolicy(Qt.NoFocus) self.__rhsResetButton.setEnabled(False) self.__rhsResetButton.setToolTip("Reset revision to compare") self.__rhsResetButton.clicked.connect(self.__onRHSReset) lhsLayout = QHBoxLayout() lhsLayout.addWidget(self.__lhsRevisionLabel) lhsLayout.addWidget(self.__lhsResetButton) rhsLayout = QHBoxLayout() rhsLayout.addWidget(self.__rhsRevisionLabel) rhsLayout.addWidget(self.__rhsResetButton) bothLayout = QVBoxLayout() bothLayout.addLayout(lhsLayout) bothLayout.addLayout(rhsLayout) revisionLayout.addLayout(bothLayout) self.__diffButton = QToolButton() self.__diffButton.setText("Diff") self.__diffButton.setFocusPolicy(Qt.NoFocus) self.__diffButton.setEnabled(False) self.__diffButton.clicked.connect(self.__onDiff) revisionLayout.addWidget(self.__diffButton) vboxLayout.addWidget(compareGroupbox) # Log table logHeaderFrame = QFrame() logHeaderFrame.setFrameStyle(QFrame.StyledPanel) logHeaderFrame.setAutoFillBackground(True) self.__setLightPalette(logHeaderFrame) logHeaderFrame.setFixedHeight(24) logHeaderLayout = QHBoxLayout() logHeaderLayout.setContentsMargins(3, 0, 0, 0) logHeaderLayout.addWidget(QLabel("Subversion log of " + self.__path)) logHeaderFrame.setLayout(logHeaderLayout) vboxLayout.addWidget(logHeaderFrame) self.__logView = QTreeWidget() self.__logView.setAlternatingRowColors(True) self.__logView.setRootIsDecorated(False) self.__logView.setItemsExpandable(False) self.__logView.setSortingEnabled(True) self.__logView.setItemDelegate(NoOutlineHeightDelegate(4)) self.__logViewHeader = QTreeWidgetItem( ["", "", "Revision", "Date", "Author", "Message"]) self.__logView.setHeaderItem(self.__logViewHeader) self.__logView.header().setSortIndicator(REVISION_COL, Qt.AscendingOrder) self.__logView.itemChanged.connect(self.__onLogViewChanged) vboxLayout.addWidget(self.__logView) # Diff part diffHeaderFrame = QFrame() diffHeaderFrame.setFrameStyle(QFrame.StyledPanel) diffHeaderFrame.setAutoFillBackground(True) self.__setLightPalette(diffHeaderFrame) diffHeaderFrame.setFixedHeight(24) diffLabel = QLabel("Diff") diffExpandingSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding) self.__showHideDiffButton = QToolButton() self.__showHideDiffButton.setAutoRaise(True) self.__showHideDiffButton.setIcon(getIcon('less.png')) self.__showHideDiffButton.setFixedSize(20, 20) self.__showHideDiffButton.setToolTip("Show diff") self.__showHideDiffButton.setFocusPolicy(Qt.NoFocus) self.__showHideDiffButton.clicked.connect(self.__onShowHideDiff) diffLayout = QHBoxLayout() diffLayout.setContentsMargins(3, 0, 0, 0) diffLayout.addWidget(diffLabel) diffLayout.addSpacerItem(diffExpandingSpacer) diffLayout.addWidget(self.__showHideDiffButton) diffHeaderFrame.setLayout(diffLayout) self.__diffViewer = DiffTabWidget() self.__diffViewer.setHTML(self.NODIFF) self.__diffViewer.setVisible(False) vboxLayout.addWidget(diffHeaderFrame) vboxLayout.addWidget(self.__diffViewer) # Buttons at the bottom buttonBox = QDialogButtonBox(self) buttonBox.setOrientation(Qt.Horizontal) buttonBox.setStandardButtons(QDialogButtonBox.Ok) buttonBox.button(QDialogButtonBox.Ok).setDefault(True) buttonBox.accepted.connect(self.close) vboxLayout.addWidget(buttonBox)
class SearchResultsViewer(QWidget): """Search results viewer tab widget""" def __init__(self, parent=None): QWidget.__init__(self, parent) self.__results = QStackedWidget(self) 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) self.__createLayout(parent) self.__updateButtonsStatus() GlobalData().project.sigProjectChanged.connect(self.__onProjectChanged) def __createLayout(self, parent): """Creates the toolbar and layout""" del parent # unused argument # Buttons etc. self.clearButton = QAction(getIcon('trash.png'), 'Delete current results', self) self.clearButton.triggered.connect(self.__clear) self.prevButton = QAction(getIcon('1leftarrow.png'), 'Previous results', self) self.prevButton.triggered.connect(self.__previous) self.nextButton = QAction(getIcon('1rightarrow.png'), 'Next results', self) self.nextButton.triggered.connect(self.__next) self.doAgainButton = QAction(getIcon('searchagain.png'), 'Do again', self) self.doAgainButton.triggered.connect(self.__doAgain) self.removeItemButton = QAction(getIcon('delitem.png'), 'Remove currently selected item (Del)', self) self.removeItemButton.triggered.connect(self.__removeItem) # 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.prevButton) self.toolbar.addAction(self.nextButton) self.toolbar.addAction(self.doAgainButton) self.toolbar.addWidget(ToolBarExpandingSpacer(self.toolbar)) self.toolbar.addAction(self.removeItemButton) self.toolbar.addAction(self.clearButton) 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.__results) self.__results.hide() self.setLayout(self.__hLayout) def __isReportShown(self): """True is any of the reports is shown""" return self.__results.count() > 0 def getResultsViewer(self): """Provides a reference to the results tree""" return self.__results def __updateButtonsStatus(self): """Updates the buttons status""" if self.__isReportShown(): index = self.__results.currentIndex() widget = self.__results.currentWidget() self.prevButton.setEnabled(index > 0) self.nextButton.setEnabled(index < self.__results.count() - 1) self.doAgainButton.setEnabled(widget.canDoAgain()) self.removeItemButton.setEnabled(widget.selectedItem is not None) self.clearButton.setEnabled(True) else: self.prevButton.setEnabled(False) self.nextButton.setEnabled(False) self.doAgainButton.setEnabled(False) self.removeItemButton.setEnabled(False) self.clearButton.setEnabled(False) def __updateIndicators(self): """Updates all the indicators""" total = self.__results.count() for index in range(total): self.__results.widget(index).updateIndicator(index + 1, total) def setFocus(self): """Overridden setFocus""" self.__hLayout.setFocus() def __onProjectChanged(self, what): """Triggered when a project is changed""" if what == CodimensionProject.CompleteProject: self.__saveProjectResults() self.__populateForProject() def __connectBufferChange(self): """Connects the sigBufferChange""" if not self.__bufferChangeConnected: self.__bufferChangeConnected = True mainWindow = GlobalData().mainWindow editorsManager = mainWindow.editorsManagerWidget.editorsManager editorsManager.sigBufferModified.connect(self.onBufferModified) def __disconnectBufferChange(self): """Disconnects the sigBufferModified signal""" if self.__bufferChangeConnected: self.__bufferChangeConnected = False mainWindow = GlobalData().mainWindow editorsManager = mainWindow.editorsManagerWidget.editorsManager editorsManager.sigBufferModified.disconnect(self.onBufferModified) def onBufferModified(self, fileName, uuid): """Triggered when a buffer is modified""" for index in range(self.__results.count()): self.__results.widget(index).resultsTree.onBufferModified( fileName, uuid) def __previous(self): """Switch to the previous results""" if self.__isReportShown(): index = self.__results.currentIndex() if index > 0: self.__results.setCurrentIndex(index - 1) self.__updateButtonsStatus() def __next(self): """Switch to the next results""" if self.__isReportShown(): index = self.__results.currentIndex() if index < self.__results.count() - 1: self.__results.setCurrentIndex(index + 1) self.__updateButtonsStatus() def keyPressEvent(self, event): """Del key processing""" if event.key() == Qt.Key_Delete: event.accept() self.__removeItem() else: QWidget.keyPressEvent(self, event) def __removeItem(self): """Removes one entry of the search""" widget = self.__results.currentWidget() if widget.selectedItem is None: return widget.removeSelectedItem() if widget.resultsTree.topLevelItemCount() == 0: # The last result, need to remove the search result self.__clear() else: self.__updateButtonsStatus() def __clear(self): """Clears the content of the vertical layout""" if not self.__isReportShown(): return index = self.__results.currentIndex() widget = self.__results.currentWidget() widget.clear() if self.__results.count() == 1: self.__results.hide() self.__noneLabel.show() self.__disconnectBufferChange() self.__results.removeWidget(widget) widget.deleteLater() if self.__results.count() > 0: if index >= self.__results.count(): index -= 1 self.__results.setCurrentIndex(index) self.__updateButtonsStatus() self.__updateIndicators() def __doAgain(self): """Performs the action once again""" if self.__isReportShown(): self.__results.currentWidget().doAgain(self) def showReport(self, providerId, results, parameters, searchId=None): """Shows the find in files results""" # Memorize the screen width searchTooltip.setScreenWidth( GlobalData().application.desktop().screenGeometry().width()) if searchId is None: resultWidget = ResultsViewerWidget(providerId, results, parameters, str(uuid1()), self) index = self.__results.addWidget(resultWidget) else: # Find the widget with this searchId found = False for index in range(self.__results.count()): if self.__results.widget(index).searchId == searchId: found = True break if not found: # add as a new one resultWidget = ResultsViewerWidget(providerId, results, parameters, str(uuid1()), self) index = self.__results.addWidget(resultWidget) else: # Repopulate it widget = self.__results.widget(index) widget.populate(results) self.__results.setCurrentIndex(index) # Show the complete information self.__noneLabel.hide() self.__results.show() self.__updateButtonsStatus() self.__updateIndicators() self.__connectBufferChange() def __populateForProject(self): """Load the project saved search results""" def __saveProjectResults(self): """Serialize to the disk the search results"""
class ResultsViewerWidget(QWidget): """A header plus a tree widget""" def __init__(self, providerId, results, parameters, searchId, parent): QWidget.__init__(self, parent) self.__providerId = providerId self.__parameters = parameters self.searchId = searchId self.selectedItem = None self.__removeItemButton = parent.removeItemButton self.resultsTree = SearchResultsTreeWidget() self.resultsTree.itemSelectionChanged.connect( self.__selectionChanged) self.indicator = HeaderLabel() self.providerLabel = HeaderLabel( GlobalData().searchProviders[providerId].getName()) self.providerLabel.setToolTip('Results provider') self.timestampLabel = HeaderLabel() self.timestampLabel.setToolTip('Search timestamp') self.__labelLayout = QHBoxLayout() self.__labelLayout.setContentsMargins(0, 0, 0, 0) self.__labelLayout.setSpacing(4) self.__labelLayout.addWidget(self.indicator) self.__labelLayout.addWidget(self.providerLabel) # There could be many labels with the search parameters for item in GlobalData().searchProviders[providerId].serialize(parameters): paramLabel = HeaderFitLabel() paramLabel.setText('%s: %s' % item) paramLabel.setAlignment(Qt.AlignLeft) paramLabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.__labelLayout.addWidget(paramLabel) self.__labelLayout.addWidget(self.timestampLabel) self.__vLayout = QVBoxLayout() self.__vLayout.setContentsMargins(0, 0, 0, 0) self.__vLayout.setSpacing(4) self.__vLayout.addLayout(self.__labelLayout) self.__vLayout.addWidget(self.resultsTree) self.setLayout(self.__vLayout) self.populate(results) def populate(self, results): """Populates data in the tree widget""" self.clear() self.timestampLabel.setText(getLocaleDateTime()) # 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) _, icon, _ = getFileProperties(item.fileName) fileItem.setIcon(0, icon) 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) self.resultsTree.header().setSectionResizeMode(1, QHeaderView.Fixed) self.resultsTree.header().resizeSection(1, 30) self.resultsTree.buildCache() def updateIndicator(self, own, total): """Updates the indicator label and tooltip""" self.indicator.setText('%d of %d' % (own, total)) self.indicator.setToolTip('Search result %d out of %d' % (own, total)) def clear(self): """Clean up""" self.resultsTree.resetCache() self.resultsTree.clear() self.selectedItem = None def __selectionChanged(self): """Selection of an item changed""" selected = list(self.resultsTree.selectedItems()) if selected: self.selectedItem = selected[0] self.__removeItemButton.setEnabled(True) else: self.selectedItem = None self.__removeItemButton.setEnabled(False) def removeSelectedItem(self): """Removes the selected item""" if self.selectedItem is None: return if isinstance(self.selectedItem, MatchTableFileItem): # This is a top level item topItemIndex = self.resultsTree.indexOfTopLevelItem( self.selectedItem) self.resultsTree.takeTopLevelItem(topItemIndex) else: # This is a file item, i.e. a child parentItem = self.selectedItem.parent() childIndex = parentItem.indexOfChild(self.selectedItem) parentItem.takeChild(childIndex) if parentItem.childCount() == 0: # The top level item needs to be deleted too topItemIndex = self.resultsTree.indexOfTopLevelItem( parentItem) self.resultsTree.takeTopLevelItem(topItemIndex) if self.resultsTree.topLevelItemCount() > 0: self.__updateCounters() def __updateCounters(self): """Updates the counters after a match is deleted""" total = 0 fileCount = self.resultsTree.topLevelItemCount() for index in range(fileCount): topLevelItem = self.resultsTree.topLevelItem(index) matchCount = topLevelItem.childCount() if matchCount == 1: matchText = " (1 match)" else: matchText = " (" + str(matchCount) + " matches)" total += matchCount topLevelItem.setText(2, matchText) headerLabels = ["File name / line (total files: " + str(fileCount) + ")", '', "Text (total matches: " + str(total) + ")"] self.resultsTree.setHeaderLabels(headerLabels) def doAgain(self, resultsViewer): """Performs the same search again""" GlobalData().searchProviders[self.__providerId].searchAgain( self.searchId, self.__parameters, resultsViewer) def canDoAgain(self): """Tells if the do again functionality is available""" if self.__providerId == OccurrencesSearchProvider.getName(): # There are too many cases when it is problematic to do again # jedi needs to have a source code and a cursor position in it # however, at least following may brake the search: # - the buffer has been changed (could be tracked) # - the file was closed so there is no more editor (could be # reloaded) # - the file was changed outside of the ide (cannot be tracked) # - the file is changed between the ide sessions when the feature # of saving/restoring results is implemented (cannot be tracked) # So for now the redo is just disabled for this provider return False return True
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.__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() # Create the path label self.__pathLabel = HeaderFitLabel(self) 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.__pathLabel.setMinimumWidth(40) self.__layout.addWidget(self.__pathLabel) self.__spacer = ToolBarExpandingSpacer(self) self.__spacer.setMinimumWidth(0) self.__layout.addWidget(self.__spacer) # Create the selection label self.__selectionLabel = HeaderLabel('', None, self) 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 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 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)
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)
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 __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)