class EditorContextMenuMixin: """Encapsulates the context menu handling""" def __init__(self): self.encodingReloadMenu = QMenu("Set &encoding and reload") self.encodingReloadActGrp = QActionGroup(self) self.encodingWriteMenu = QMenu("Set encodin&g") self.encodingWriteActGrp = QActionGroup(self) mainWindow = GlobalData().mainWindow editorsManager = mainWindow.editorsManagerWidget.editorsManager self._menu = QMenu(self) self.__menuUndo = self._menu.addAction(getIcon('undo.png'), '&Undo', self.onUndo, "Ctrl+Z") self.__menuRedo = self._menu.addAction(getIcon('redo.png'), '&Redo', self.onRedo, "Ctrl+Y") self._menu.addSeparator() self.__menuCut = self._menu.addAction(getIcon('cutmenu.png'), 'Cu&t', self.onShiftDel, "Ctrl+X") self.__menuCopy = self._menu.addAction(getIcon('copymenu.png'), '&Copy', self.onCtrlC, "Ctrl+C") self.__menuPaste = self._menu.addAction(getIcon('pastemenu.png'), '&Paste', self.paste, "Ctrl+V") self.__menuSelectAll = self._menu.addAction( getIcon('selectallmenu.png'), 'Select &all', self.selectAll, "Ctrl+A") self._menu.addSeparator() self.__initReloadEncodingMenu() self.encodingReloadMenu.setIcon(getIcon('textencoding.png')) self._menu.addMenu(self.encodingReloadMenu) self.__initWriteEncodingMenu() self.encodingWriteMenu.setIcon(getIcon('textencoding.png')) menu = self._menu.addMenu(self.encodingWriteMenu) self.__menuClearEncoding = self._menu.addAction( getIcon('clearmenu.png'), 'Clear explicit encoding', self.__onClearEncoding) self._menu.addSeparator() menu = self._menu.addMenu(self.__initToolsMenu()) menu.setIcon(getIcon('toolsmenu.png')) self._menu.addSeparator() menu = self._menu.addMenu(self.__initDiagramsMenu()) menu.setIcon(getIcon('diagramsmenu.png')) self._menu.addSeparator() self.__menuOpenAsFile = self._menu.addAction(getIcon('filemenu.png'), 'O&pen as file', self.openAsFile) self.__menuDownloadAndShow = self._menu.addAction( getIcon('filemenu.png'), 'Do&wnload and show', self.downloadAndShow) self.__menuOpenInBrowser = self._menu.addAction( getIcon('homepagemenu.png'), 'Open in browser', self.openInBrowser) self._menu.addSeparator() self._menuHighlightInPrj = self._menu.addAction( getIcon("highlightmenu.png"), "&Highlight in project browser", editorsManager.onHighlightInPrj) self._menuHighlightInFS = self._menu.addAction( getIcon("highlightmenu.png"), "H&ighlight in file system browser", editorsManager.onHighlightInFS) self._menuHighlightInOutline = self._menu.addAction( getIcon("highlightmenu.png"), "Highlight in &outline browser", self.highlightInOutline, 'Ctrl+B') # Plugins support self.__pluginMenuSeparator = self._menu.addSeparator() registeredMenus = editorsManager.getPluginMenus() if registeredMenus: for path in registeredMenus: self._menu.addMenu(registeredMenus[path]) else: self.__pluginMenuSeparator.setVisible(False) editorsManager.sigPluginContextMenuAdded.connect( self._onPluginMenuAdded) editorsManager.sigPluginContextMenuRemoved.connect( self._onPluginMenuRemoved) def __initReloadEncodingMenu(self): """Creates the encoding menu for reloading the existing file""" for encoding in sorted(SUPPORTED_CODECS): act = self.encodingReloadMenu.addAction(encoding) act.setCheckable(True) act.setData(encoding) self.encodingReloadActGrp.addAction(act) self.encodingReloadMenu.triggered.connect(self.__onReloadWithEncoding) def __initWriteEncodingMenu(self): """Creates the encoding menu for further read/write operations""" for encoding in sorted(SUPPORTED_CODECS): act = self.encodingWriteMenu.addAction(encoding) act.setCheckable(True) act.setData(encoding) self.encodingWriteActGrp.addAction(act) self.encodingWriteMenu.triggered.connect(self.__onReadWriteEncoding) def __initToolsMenu(self): """Creates the tools menu""" self.toolsMenu = QMenu('Python too&ls') self.runAct = self.toolsMenu.addAction(getIcon('run.png'), 'Run script', self._parent.onRunScript) self.runParamAct = self.toolsMenu.addAction( getIcon('paramsmenu.png'), 'Set parameters and run', self._parent.onRunScriptDlg) self.toolsMenu.addSeparator() self.profileAct = self.toolsMenu.addAction( getIcon('profile.png'), 'Profile script', self._parent.onProfileScript) self.profileParamAct = self.toolsMenu.addAction( getIcon('paramsmenu.png'), 'Set parameters and profile', self._parent.onProfileScriptDlg) self.toolsMenu.addSeparator() self.disasmMenu = QMenu('Disassembly') self.disasmMenu.setIcon(getIcon('disassembly.png')) self.disasmAct0 = self.disasmMenu.addAction( getIcon(''), 'Disassembly (no optimization)', self._onDisasm0) self.disasmAct1 = self.disasmMenu.addAction( getIcon(''), 'Disassembly (optimization level 1)', self._onDisasm1) self.disasmAct2 = self.disasmMenu.addAction( getIcon(''), 'Disassembly (optimization level 2)', self._onDisasm2) self.toolsMenu.addMenu(self.disasmMenu) return self.toolsMenu def __initDiagramsMenu(self): """Creates the diagrams menu""" self.diagramsMenu = QMenu("&Diagrams") self.importsDgmAct = self.diagramsMenu.addAction( getIcon('importsdiagram.png'), 'Imports diagram', self._parent.onImportDgm) self.importsDgmParamAct = self.diagramsMenu.addAction( getIcon('paramsmenu.png'), 'Fine tuned imports diagram', self._parent.onImportDgmTuned) return self.diagramsMenu def contextMenuEvent(self, event): """Called just before showing a context menu""" # Accepting needs to suppress the native menu event.accept() isPython = self.isPythonBuffer() readOnly = self.isReadOnly() self.__menuUndo.setEnabled(self.document().isUndoAvailable()) self.__menuRedo.setEnabled(self.document().isRedoAvailable()) self.__menuCut.setEnabled(not readOnly) self.__menuPaste.setEnabled(QApplication.clipboard().text() != "" and not readOnly) fileName = self._parent.getFileName() absFileName = os.path.isabs(fileName) self.__menuOpenAsFile.setEnabled(self.openAsFileAvailable()) self.__menuDownloadAndShow.setEnabled(self.downloadAndShowAvailable()) self.__menuOpenInBrowser.setEnabled(self.downloadAndShowAvailable()) self._menuHighlightInPrj.setEnabled( absFileName and GlobalData().project.isProjectFile(fileName)) self._menuHighlightInFS.setEnabled(absFileName) self._menuHighlightInOutline.setEnabled(isPython) self._menuHighlightInOutline.setEnabled(isPython) self.toolsMenu.setEnabled(isPython) if isPython: runEnabled = self._parent.runScriptButton.isEnabled() self.runAct.setEnabled(runEnabled) self.runParamAct.setEnabled(runEnabled) self.profileAct.setEnabled(runEnabled) self.profileParamAct.setEnabled(runEnabled) if absFileName: self.__menuClearEncoding.setEnabled( getFileEncoding(fileName) is not None) else: self.__menuClearEncoding.setEnabled( self.explicitUserEncoding is not None) # Check the proper encoding in the menu encoding = 'undefined' if absFileName: enc = getFileEncoding(fileName) if enc: encoding = enc else: if self.explicitUserEncoding: encoding = self.explicitUserEncoding encoding = getNormalizedEncoding(encoding, False) if absFileName: for act in self.encodingReloadActGrp.actions(): act.setChecked(encoding == getNormalizedEncoding(act.data())) else: self.encodingReloadMenu.setEnabled(False) for act in self.encodingWriteActGrp.actions(): act.setChecked(encoding == getNormalizedEncoding(act.data())) # Show the menu self._menu.popup(event.globalPos()) def __isSameEncodingAsCurrent(self, enc): """True if the same encoding has already been set""" fileName = self._parent.getFileName() if not os.path.isabs(fileName): # New unsaved yet file if not self.explicitUserEncoding: return False return getNormalizedEncoding(enc) == getNormalizedEncoding( self.explicitUserEncoding) # Existed before or just saved new file currentEnc = getFileEncoding(fileName) if not currentEnc: return False return getNormalizedEncoding(currentEnc) == getNormalizedEncoding(enc) def __onReloadWithEncoding(self, act): """Triggered when encoding is selected""" # The method is called only for the existing disk files encoding = act.data() if self.__isSameEncodingAsCurrent(encoding): return if self.document().isModified(): res = QMessageBox.warning( self, 'Continue loosing changes', '<p>The buffer has unsaved changes. Are you sure to continue ' 'reloading the content using ' + encoding + ' encoding and ' 'loosing the changes?</p>', QMessageBox.StandardButtons(QMessageBox.Cancel | QMessageBox.Yes), QMessageBox.Cancel) if res == QMessageBox.Cancel: return # Do the reload fileName = self._parent.getFileName() setFileEncoding(fileName, encoding) self.__updateFilePosition() self.readFile(fileName) self.__restoreFilePosition() self.__updateMainWindowStatusBar() def __onReadWriteEncoding(self, act): """Sets explicit encoding for further read/write ops""" encoding = act.data() if self.__isSameEncodingAsCurrent(encoding): return # fileName = self._parent.getFileName() # absFileName = os.path.isabs(fileName) self.document().setModified(True) self.explicitUserEncoding = encoding self.__updateMainWindowStatusBar() def __onClearEncoding(self): """Clears the explicitly set encoding""" self.explicitUserEncoding = None fileName = self._parent.getFileName() absFileName = os.path.isabs(fileName) if absFileName: setFileEncoding(fileName, None) self.encoding = detectEncodingOnClearExplicit(fileName, self.text) self.__updateMainWindowStatusBar() def onUndo(self): """Undo implementation""" if self.document().isUndoAvailable(): self.undo() self._parent.modificationChanged() def onRedo(self): """Redo implementation""" if self.document().isRedoAvailable(): self.redo() self._parent.modificationChanged() def _onPluginMenuAdded(self, menu, count): """Triggered when a new menu was added""" del count # unused argument self._menu.addMenu(menu) self.__pluginMenuSeparator.setVisible(True) def __onDisasm(self, optimization): """Common implementation""" if self.isPythonBuffer(): if os.path.isabs(self._parent.getFileName()): if not self._parent.isModified(): GlobalData().mainWindow.showFileDisassembly( self._parent.getFileName(), optimization) return fileName = self._parent.getFileName() if not fileName: fileName = self._parent.getShortName() encoding = self.encoding if not encoding: encoding = detectNewFileWriteEncoding(self, fileName) GlobalData().mainWindow.showBufferDisassembly( self.text, encoding, fileName, optimization) def _onDisasm0(self): """Triggered to disassemble the buffer without optimization""" self.__onDisasm(OPT_NO_OPTIMIZATION) def _onDisasm1(self): """Triggered to disassemble the buffer with optimization level 1""" self.__onDisasm(OPT_OPTIMIZE_ASSERT) def _onDisasm2(self): """Triggered to disassemble the buffer with optimization level 2""" self.__onDisasm(OPT_OPTIMIZE_DOCSTRINGS) def _onPluginMenuRemoved(self, menu, count): """Triggered when a menu was deleted""" self._menu.removeAction(menu.menuAction()) self.__pluginMenuSeparator.setVisible(count != 0) def highlightInOutline(self): """Triggered when highlight in outline browser is requested""" if self.isPythonBuffer(): info = getBriefModuleInfoFromMemory(self.text) context = getContext(self, info, True, False) line, _ = self.cursorPosition GlobalData().mainWindow.highlightInOutline(context, int(line) + 1) self.setFocus() def terminateMenus(self): """Called when the tab is closed""" self.encodingReloadMenu.triggered.disconnect( self.__onReloadWithEncoding) self.encodingReloadMenu.deleteLater() self.encodingReloadActGrp.deleteLater() self.encodingWriteMenu.triggered.disconnect(self.__onReadWriteEncoding) self.encodingWriteMenu.deleteLater() self.encodingWriteActGrp.deleteLater() self.toolsMenu.deleteLater() self.disasmMenu.deleteLater() self.diagramsMenu.deleteLater() self._menu.deleteLater() mainWindow = GlobalData().mainWindow editorsManager = mainWindow.editorsManagerWidget.editorsManager editorsManager.sigPluginContextMenuAdded.disconnect( self._onPluginMenuAdded) editorsManager.sigPluginContextMenuRemoved.disconnect( self._onPluginMenuRemoved) @staticmethod def __updateMainWindowStatusBar(): """Updates the main window status bar""" mainWindow = GlobalData().mainWindow editorsManager = mainWindow.editorsManagerWidget.editorsManager editorsManager.updateStatusBar() @staticmethod def __updateFilePosition(): """Updates the position in a file""" mainWindow = GlobalData().mainWindow editorsManager = mainWindow.editorsManagerWidget.editorsManager editorsManager.updateFilePosition(None) @staticmethod def __restoreFilePosition(): """Restores the position in a file""" mainWindow = GlobalData().mainWindow editorsManager = mainWindow.editorsManagerWidget.editorsManager editorsManager.restoreFilePosition(None)
class PylintPlugin(WizardInterface): """Codimension pylint plugin""" def __init__(self): WizardInterface.__init__(self) self.__pylintDriver = None self.__resultViewer = None self.__bufferRunAction = None self.__bufferGenerateAction = None self.__globalShortcut = None self.__mainMenu = None self.__mainMenuSeparator = None self.__mainRunAction = None self.__mainGenerateAction = None @staticmethod def isIDEVersionCompatible(ideVersion): """Checks if the IDE version is compatible with the plugin. Codimension makes this call before activating a plugin. The passed ideVersion is a string representing the current IDE version. True should be returned if the plugin is compatible with the IDE. """ return StrictVersion(ideVersion) >= StrictVersion('4.7.1') def activate(self, ideSettings, ideGlobalData): """Activates the plugin. The plugin may override the method to do specific plugin activation handling. ideSettings - reference to the IDE Settings singleton see codimension/src/utils/settings.py ideGlobalData - reference to the IDE global settings see codimension/src/utils/globals.py Note: if overriden do not forget to call the base class activate() """ WizardInterface.activate(self, ideSettings, ideGlobalData) self.__resultViewer = PylintResultViewer(self.ide, PLUGIN_HOME_DIR) self.ide.sideBars['bottom'].addTab( self.__resultViewer, QIcon(PLUGIN_HOME_DIR + 'pylint.png'), 'Pylint', 'pylint', 2) self.ide.sideBars['bottom'].tabButton('pylint', QTabBar.RightSide).resize(0, 0) # The clear call must be here, not in the results viewer __init__() # This is because the viewer has not been inserted into the side bar at # the time of __init__() so the tooltip setting does not work self.__resultViewer.clear() self.__pylintDriver = PylintDriver(self.ide) self.__pylintDriver.sigFinished.connect(self.__pylintFinished) if self.__globalShortcut is None: self.__globalShortcut = QShortcut(QKeySequence('Ctrl+L'), self.ide.mainWindow, self.__run) else: self.__globalShortcut.setKey('Ctrl+L') # Add buttons for _, _, tabWidget in self.ide.editorsManager.getTextEditors(): self.__addButton(tabWidget) # File type changed & new tab self.ide.editorsManager.sigTextEditorTabAdded.connect( self.__textEditorTabAdded) self.ide.editorsManager.sigFileTypeChanged.connect( self.__fileTypeChanged) # Add main menu self.__mainMenu = QMenu('Pylint', self.ide.mainWindow) self.__mainMenu.setIcon(QIcon(PLUGIN_HOME_DIR + 'pylint.png')) self.__mainRunAction = self.__mainMenu.addAction( QIcon(PLUGIN_HOME_DIR + 'pylint.png'), 'Run pylint\t(Ctrl+L)', self.__run) self.__mainGenerateAction = self.__mainMenu.addAction( QIcon(PLUGIN_HOME_DIR + 'generate.png'), 'Generate/open pylintrc file', self.__generate) toolsMenu = self.ide.mainWindow.menuBar().findChild(QMenu, 'tools') self.__mainMenuSeparator = toolsMenu.addSeparator() toolsMenu.addMenu(self.__mainMenu) self.__mainMenu.aboutToShow.connect(self.__mainMenuAboutToShow) def deactivate(self): """Deactivates the plugin. The plugin may override the method to do specific plugin deactivation handling. Note: if overriden do not forget to call the base class deactivate() """ self.__globalShortcut.setKey(0) self.__resultViewer = None self.ide.sideBars['bottom'].removeTab('pylint') self.__pylintDriver = None # Remove buttons for _, _, tabWidget in self.ide.editorsManager.getTextEditors(): pylintAction = tabWidget.toolbar.findChild(QAction, 'pylint') tabWidget.toolbar.removeAction(pylintAction) # deleteLater() is essential. Otherwise the button is not removed # really from the list of children pylintAction.deleteLater() tabWidget.getEditor().modificationChanged.disconnect( self.__modificationChanged) self.ide.editorsManager.sigTextEditorTabAdded.disconnect( self.__textEditorTabAdded) self.ide.editorsManager.sigFileTypeChanged.disconnect( self.__fileTypeChanged) # Remove main menu items self.__mainRunAction.deleteLater() self.__mainRunAction = None self.__mainGenerateAction.deleteLater() self.__mainGenerateAction = None self.__mainMenu.deleteLater() self.__mainMenu = None self.__mainMenuSeparator.deleteLater() self.__mainMenuSeparator = None WizardInterface.deactivate(self) def getConfigFunction(self): """Provides a plugun configuration function. The plugin can provide a function which will be called when the user requests plugin configuring. If a plugin does not require any config parameters then None should be returned. By default no configuring is required. """ return self.configure def populateMainMenu(self, parentMenu): """Populates the main menu. The main menu looks as follows: Plugins - Plugin manager (fixed item) - Separator (fixed item) - <Plugin #1 name> (this is the parentMenu passed) ... If no items were populated by the plugin then there will be no <Plugin #N name> menu item shown. It is suggested to insert plugin configuration item here if so. """ del parentMenu # unused argument def populateFileContextMenu(self, parentMenu): """Populates the file context menu. The file context menu shown in the project viewer window will have an item with a plugin name and subitems which are populated here. If no items were populated then the plugin menu item will not be shown. When a callback is called the corresponding menu item will have attached data with an absolute path to the item. """ del parentMenu # unused argument def populateDirectoryContextMenu(self, parentMenu): """Populates the directory context menu. The directory context menu shown in the project viewer window will have an item with a plugin name and subitems which are populated here. If no items were populated then the plugin menu item will not be shown. When a callback is called the corresponding menu item will have attached data with an absolute path to the directory. """ del parentMenu # unused argument def populateBufferContextMenu(self, parentMenu): """Populates the editing buffer context menu. The buffer context menu shown for the current edited/viewed file will have an item with a plugin name and subitems which are populated here. If no items were populated then the plugin menu item will not be shown. Note: when a buffer context menu is selected by the user it always refers to the current widget. To get access to the current editing widget the plugin can use: self.ide.currentEditorWidget The widget could be of different types and some circumstances should be considered, e.g.: - it could be a new file which has not been saved yet - it could be modified - it could be that the disk file has already been deleted - etc. Having the current widget reference the plugin is able to retrieve the information it needs. """ parentMenu.setIcon(QIcon(PLUGIN_HOME_DIR + 'pylint.png')) self.__bufferRunAction = parentMenu.addAction( QIcon(PLUGIN_HOME_DIR + 'pylint.png'), 'Run pylint\t(Ctrl+L)', self.__run) self.__bufferGenerateAction = parentMenu.addAction( QIcon(PLUGIN_HOME_DIR + 'generate.png'), 'Generate/open pylintrc file', self.__generate) parentMenu.aboutToShow.connect(self.__bufferMenuAboutToShow) def configure(self): """Configure dialog""" PylintPluginConfigDialog(PLUGIN_HOME_DIR, self.ide.mainWindow).exec_() def __canRun(self, editorWidget): """Tells if pylint can be run for the given editor widget""" if self.__pylintDriver.isInProcess(): return False, None if editorWidget.getType() != MainWindowTabWidgetBase.PlainTextEditor: return False, None if not isPythonMime(editorWidget.getMime()): return False, None if editorWidget.isModified(): return False, 'Save changes before running pylint' if not os.path.isabs(editorWidget.getFileName()): return False, 'The new file has never been saved yet. ' \ 'Save it before running pylint' return True, None def __run(self): """Runs the pylint analysis""" editorWidget = self.ide.currentEditorWidget canRun, message = self.__canRun(editorWidget) if not canRun: if message: self.ide.showStatusBarMessage(message) return enc = editorWidget.getEncoding() message = self.__pylintDriver.start(editorWidget.getFileName(), enc) if message is None: self.__switchToRunning() else: logging.error(message) def __generate(self): """[Generates and] opens the pylintrc file""" editorWidget = self.ide.currentEditorWidget fileName = editorWidget.getFileName() if not os.path.isabs(fileName): fileName = None rcfile = self.__pylintDriver.getPylintrc(self.ide, fileName) if not rcfile: if fileName is None and not self.ide.project.isLoaded(): logging.error('Cannot generate pylintrc. ' 'The current buffer file has not been saved yet ' 'and there is no project') return QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) rcfile = self.__pylintDriver.generateRCFile(self.ide, fileName) QApplication.restoreOverrideCursor() if rcfile: if os.path.exists(rcfile): self.ide.mainWindow.openFile(rcfile, 0) return # It really could be only the rc generating error logging.error('Error generating pylintrc file ' + str(rcfile)) def __pylintFinished(self, results): """Pylint has finished""" self.__switchToIdle() error = results.get('ProcessError', None) if error: logging.error(error) else: self.__resultViewer.showResults(results) self.ide.mainWindow.activateBottomTab('pylint') def __switchToRunning(self): """Switching to the running mode""" QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) # disable buttons for _, _, tabWidget in self.ide.editorsManager.getTextEditors(): pylintAction = tabWidget.toolbar.findChild(QAction, 'pylint') if pylintAction is not None: pylintAction.setEnabled(False) # disable menu def __switchToIdle(self): """Switching to the idle mode""" QApplication.restoreOverrideCursor() # enable buttons for _, _, tabWidget in self.ide.editorsManager.getTextEditors(): pylintAction = tabWidget.toolbar.findChild(QAction, 'pylint') if pylintAction is not None: pylintAction.setEnabled(self.__canRun(tabWidget)[0]) # enable menu def __addButton(self, tabWidget): """Adds a button to the editor toolbar""" pylintButton = QAction(QIcon(PLUGIN_HOME_DIR + 'pylint.png'), 'Run pylint (Ctrl+L)', tabWidget.toolbar) pylintButton.setEnabled(self.__canRun(tabWidget)[0]) pylintButton.triggered.connect(self.__run) pylintButton.setObjectName('pylint') beforeWidget = tabWidget.toolbar.findChild(QAction, 'deadCodeScriptButton') tabWidget.toolbar.insertAction(beforeWidget, pylintButton) tabWidget.getEditor().modificationChanged.connect( self.__modificationChanged) def __modificationChanged(self): """Triggered when one of the text editors changed their mod state""" pylintAction = self.ide.currentEditorWidget.toolbar.findChild( QAction, 'pylint') if pylintAction is not None: pylintAction.setEnabled( self.__canRun(self.ide.currentEditorWidget)[0]) def __textEditorTabAdded(self, tabIndex): """Triggered when a new tab is added""" del tabIndex #unused argument self.__addButton(self.ide.currentEditorWidget) def __fileTypeChanged(self, shortFileName, uuid, mime): """Triggered when a file changed its type""" del shortFileName # unused argument del uuid # unused argument del mime # unused argument # Supposedly it can happened only on the current tab pylintAction = self.ide.currentEditorWidget.toolbar.findChild( QAction, 'pylint') if pylintAction is not None: pylintAction.setEnabled( self.__canRun(self.ide.currentEditorWidget)[0]) def __bufferMenuAboutToShow(self): """The buffer context menu is about to show""" runEnable, generateState = self.__calcRunGenerateState() self.__bufferRunAction.setEnabled(runEnable) self.__bufferGenerateAction.setEnabled(generateState[0]) self.__bufferGenerateAction.setText(generateState[1]) def __mainMenuAboutToShow(self): """The main menu is about to show""" runEnable, generateState = self.__calcRunGenerateState() self.__mainRunAction.setEnabled(runEnable) self.__mainGenerateAction.setEnabled(generateState[0]) self.__mainGenerateAction.setText(generateState[1]) def __calcRunGenerateState(self): """Calculates the enable/disable state of the run/generate menu items""" editorWidget = self.ide.currentEditorWidget defaultGenerateText = 'Open pylintrc file' if editorWidget.getType() != MainWindowTabWidgetBase.PlainTextEditor: return False, (False, defaultGenerateText) if not isPythonMime(editorWidget.getMime()): return False, (False, defaultGenerateText) if self.__pylintDriver.isInProcess(): return False, (False, defaultGenerateText) fileName = editorWidget.getFileName() if not os.path.isabs(fileName): fileName = None rcfile = self.__pylintDriver.getPylintrc(self.ide, fileName) if editorWidget.isModified(): if rcfile: return False, (True, defaultGenerateText) return False, (True, 'Generate and open pylintrc file') # Saved python file and no pylint running if rcfile: return fileName is not None, (True, defaultGenerateText) return fileName is not None, (True, 'Generate and open pylintrc file')