Wed, 27 Sep 2017 19:50:44 +0200
Started correcting the source code documentation.
# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2017 Detlev Offenbach <detlev@die-offenbachs.de> # """ Module implementing the Rope refactoring plugin. """ from __future__ import unicode_literals import os from PyQt5.QtCore import Qt, QObject, QTranslator, QCoreApplication from E5Gui.E5Application import e5App import Preferences import Utilities # Start-Of-Header name = "Refactoring Rope Plugin" author = "Detlev Offenbach <detlev@die-offenbachs.de>" autoactivate = True deactivateable = True version = "5.0.0" className = "RefactoringRopePlugin" packageName = "RefactoringRope" internalPackages = "rope" shortDescription = "Refactoring using the Rope library." longDescription = """This plug-in implements refactoring functionality""" \ """ using the Rope refactoring library. Additonally it implements an """ \ """ alternative auto-completion and calltips provider. Only""" \ """ refactoring, completions and calltips in the same Python variant""" \ """ as Eric is running is allowed.""" pyqtApi = 2 doNotCompile = True python2Compatible = True # End-Of-Header error = "" refactoringRopePluginObject = None def createAutoCompletionPage(configDlg): """ Module function to create the autocompletion configuration page. @param configDlg reference to the configuration dialog @return reference to the configuration page """ global refactoringRopePluginObject from RefactoringRope.ConfigurationPage.AutoCompletionRopePage \ import AutoCompletionRopePage page = AutoCompletionRopePage(refactoringRopePluginObject) return page def createCallTipsPage(configDlg): """ Module function to create the calltips configuration page. @param configDlg reference to the configuration dialog @return reference to the configuration page """ global refactoringRopePluginObject from RefactoringRope.ConfigurationPage.CallTipsRopePage \ import CallTipsRopePage page = CallTipsRopePage(refactoringRopePluginObject) return page def createMouseClickHandlerPage(configDlg): """ Module function to create the mouse click handler configuration page. @param configDlg reference to the configuration dialog @return reference to the configuration page """ global refactoringRopePluginObject from RefactoringRope.ConfigurationPage.MouseClickHandlerRopePage \ import MouseClickHandlerRopePage page = MouseClickHandlerRopePage(refactoringRopePluginObject) return page def getConfigData(): """ Module function returning data as required by the configuration dialog. @return dictionary containing the relevant data @rtype dict """ data = { "ropeAutoCompletionPage": [ QCoreApplication.translate("RefactoringRopePlugin", "Rope"), os.path.join("RefactoringRope", "ConfigurationPage", "preferences-refactoring.png"), createAutoCompletionPage, "editorAutocompletionPage", None], "ropeCallTipsPage": [ QCoreApplication.translate("RefactoringRopePlugin", "Rope"), os.path.join("RefactoringRope", "ConfigurationPage", "preferences-refactoring.png"), createCallTipsPage, "editorCalltipsPage", None], "ropeMouseClickHandlerPage": [ QCoreApplication.translate("RefactoringRopePlugin", "Rope"), os.path.join("RefactoringRope", "ConfigurationPage", "preferences-refactoring.png"), createMouseClickHandlerPage, "1editorMouseClickHandlers", None], } return data def prepareUninstall(): """ Module function to prepare for an uninstallation. """ Preferences.Prefs.settings.remove(RefactoringRopePlugin.PreferencesKey) class RefactoringRopePlugin(QObject): """ Class implementing the Rope refactoring plugin. """ PreferencesKey = "RefactoringRope" def __init__(self, ui): """ Constructor @param ui reference to the user interface object @type UI.UserInterface """ QObject.__init__(self, ui) self.__ui = ui self.__initialize() self.__defaults = { "CodeAssistEnabled": False, "MaxFixes": 10, "CodeAssistCalltipsEnabled": False, "CalltipsMaxFixes": 10, "MouseClickEnabled": True, "MouseClickGotoModifiers": int(Qt.ControlModifier), "MouseClickGotoButton": int(Qt.LeftButton), } self.__translator = None self.__loadTranslator() def __initialize(self): """ Private slot to (re)initialize the plugin. """ self.__refactoringServer = None self.__codeAssistServer = None self.__editors = [] self.__currentEditor = None self.__savedEditorName = None self.__oldEditorText = "" def activate(self): """ Public method to activate this plugin. @return tuple of None and activation status @rtype tuple of (None, bool) """ global refactoringRopePluginObject refactoringRopePluginObject = self e5App().getObject("PluginManager").shutdown.connect( self.__shutdown) from RefactoringRope.CodeAssistServer import CodeAssistServer self.__codeAssistServer = CodeAssistServer(self, self.__ui) from RefactoringRope.RefactoringServer import RefactoringServer self.__refactoringServer = RefactoringServer(self, self.__ui) self.__refactoringServer.activate() e5App().getObject("PluginManager").shutdown.connect( self.__shutdown) e5App().getObject("ViewManager").editorOpenedEd.connect( self.__editorOpened) e5App().getObject("ViewManager").editorClosedEd.connect( self.__editorClosed) if e5App().getObject("Project").isOpen(): for editor in e5App().getObject("ViewManager").getOpenEditors(): self.__editorOpened(editor) return None, True def deactivate(self): """ Public method to deactivate this plugin. """ self.__refactoringServer.deactivate() self.__codeAssistServer.deactivate() e5App().getObject("PluginManager").shutdown.disconnect( self.__shutdown) e5App().getObject("ViewManager").editorOpenedEd.disconnect( self.__editorOpened) e5App().getObject("ViewManager").editorClosedEd.disconnect( self.__editorClosed) for editor in self.__editors[:]: self.__editorClosed(editor) self.__initialize() def __shutdown(self): """ Private slot handling the shutdown signal of the plug-in manager. """ if self.__codeAssistServer: self.__codeAssistServer.deactivate() def __loadTranslator(self): """ Private method to load the translation file. """ if self.__ui is not None: loc = self.__ui.getLocale() if loc and loc != "C": locale_dir = \ os.path.join(os.path.dirname(__file__), "RefactoringRope", "i18n") translation = "rope_{0}".format(loc) translator = QTranslator(None) loaded = translator.load(translation, locale_dir) if loaded: self.__translator = translator e5App().installTranslator(self.__translator) else: print("Warning: translation file '{0}' could not" " be loaded.".format(translation)) print("Using default.") def getPreferences(self, key): """ Public method to retrieve the various refactoring settings. @param key the key of the value to get @type str @return the requested refactoring setting """ if key in ["CodeAssistEnabled", "CodeAssistCalltipsEnabled", "MouseClickEnabled"]: return Preferences.toBool(Preferences.Prefs.settings.value( self.PreferencesKey + "/" + key, self.__defaults[key])) else: return int(Preferences.Prefs.settings.value( self.PreferencesKey + "/" + key, self.__defaults[key])) def setPreferences(self, key, value): """ Public method to store the various refactoring settings. @param key the key of the setting to be set @type str @param value the value to be set """ Preferences.Prefs.settings.setValue( self.PreferencesKey + "/" + key, value) if key in ["CodeAssistEnabled", "CodeAssistCalltipsEnabled", "MouseClickEnabled"]: if value: if e5App().getObject("Project").isOpen(): for editor in e5App().getObject("ViewManager")\ .getOpenEditors(): if editor not in self.__editors: self.__editorOpened(editor) else: for editor in self.__editors[:]: self.__editorClosed(editor) elif key in ["MouseClickGotoModifiers", "MouseClickGotoButton"]: for editor in self.__editors: self.__disconnectMouseClickHandler(editor) self.__connectMouseClickHandler(editor) def __editorOpened(self, editor): """ Private slot called, when a new editor was opened. @param editor reference to the new editor @type QScintilla.Editor """ if self.__codeAssistServer.isSupportedLanguage(editor.getLanguage()): self.__connectEditor(editor) editor.languageChanged.connect(self.__editorLanguageChanged) self.__editors.append(editor) def __editorClosed(self, editor): """ Private slot called, when an editor was closed. @param editor reference to the editor @type QScintilla.Editor """ if editor in self.__editors: editor.languageChanged.disconnect(self.__editorLanguageChanged) self.__disconnectEditor(editor) self.__editors.remove(editor) def __editorLanguageChanged(self, language): """ Private slot to handle the language change of an editor. @param language programming language of the editor @type str """ editor = self.sender() if self.__codeAssistServer.isSupportedLanguage(language): if editor.getCompletionListHook("rope") is None or \ editor.getCallTipHook("rope") is None: self.__connectEditor(editor) else: self.__disconnectEditor(editor) def __connectEditor(self, editor): """ Private method to connect an editor. @param editor reference to the editor @type QScintilla.Editor """ editor.editorAboutToBeSaved.connect(self.__editorAboutToBeSaved) editor.editorSaved.connect(self.__editorSaved) if self.getPreferences("CodeAssistEnabled"): self.__setAutoCompletionHook(editor) if self.getPreferences("CodeAssistCalltipsEnabled"): self.__setCalltipsHook(editor) if self.getPreferences("MouseClickEnabled"): self.__disconnectMouseClickHandler(editor) self.__connectMouseClickHandler(editor) def __connectMouseClickHandler(self, editor): """ Private method to connect the mouse click handler to an editor. @param editor reference to the editor @type QScintilla.Editor """ if self.getPreferences("MouseClickGotoButton"): editor.setMouseClickHandler( "rope", self.getPreferences("MouseClickGotoModifiers"), self.getPreferences("MouseClickGotoButton"), self.__refactoringServer.gotoDefinition ) def __disconnectEditor(self, editor): """ Private method to disconnect an editor. @param editor reference to the editor @type QScintilla.Editor """ try: editor.editorAboutToBeSaved.disconnect(self.__editorAboutToBeSaved) editor.editorSaved.disconnect(self.__editorSaved) except TypeError: # just ignore it pass if editor.getCompletionListHook("rope"): self.__unsetAutoCompletionHook(editor) if editor.getCallTipHook("rope"): self.__unsetCalltipsHook(editor) self.__disconnectMouseClickHandler(editor) def __disconnectMouseClickHandler(self, editor): """ Private method to disconnect the mouse click handler from an editor. @param editor reference to the editor @type QScintilla.Editor """ editor.removeMouseClickHandlers("rope") def __setAutoCompletionHook(self, editor): """ Private method to set the autocompletion hook. @param editor reference to the editor @type QScintilla.Editor """ editor.addCompletionListHook("rope", self.getCompletionsList) def __unsetAutoCompletionHook(self, editor): """ Private method to unset the autocompletion hook. @param editor reference to the editor @type QScintilla.Editor """ editor.removeCompletionListHook("rope") def getCompletionsList(self, editor, context): """ Public method to get a list of possible completions. @param editor reference to the editor object, that called this method @type QScintilla.Editor @param context flag indicating to autocomplete a context @type bool @return list of possible completions @rtype list of str """ completions = self.__codeAssistServer.getCompletions(editor) return completions def __editorAboutToBeSaved(self, filename): """ Private slot to get the old contents of the named file. @param filename name of the file about to be saved @type str """ if filename and os.path.exists(filename): try: self.__oldEditorText = Utilities.readEncodedFile(filename)[0] except IOError: self.__oldEditorText = "" self.__savedEditorName = filename else: self.__savedEditorName = "" self.__oldEditorText = "" def __editorSaved(self, filename): """ Private slot to activate SOA. @param filename name of the file that was saved @type str """ if filename == self.__savedEditorName and self.__oldEditorText: self.__refactoringServer.reportChanged(self.__savedEditorName, self.__oldEditorText) self.__codeAssistServer.reportChanged(self.__savedEditorName, self.__oldEditorText) else: self.__refactoringServer.reportChanged(filename, "") self.__codeAssistServer.reportChanged(filename, "") def __setCalltipsHook(self, editor): """ Private method to set the calltip hook. @param editor reference to the editor @type QScintilla.Editor """ editor.addCallTipHook("rope", self.codeAssistCallTip) def __unsetCalltipsHook(self, editor): """ Private method to unset the calltip hook. @param editor reference to the editor @type QScintilla.Editor """ editor.removeCallTipHook("rope") def codeAssistCallTip(self, editor, pos, commas): """ Public method to return a list of calltips. @param editor reference to the editor @type QScintilla.Editor @param pos position in the text for the calltip @type int @param commas minimum number of commas contained in the calltip @type int @return list of possible calltips @rtype list of str """ cts = self.__codeAssistServer.getCallTips(pos, editor) return cts # # eflag: noqa = M801