Thu, 30 Dec 2021 11:20:07 +0100
Updated copyright for 2022.
# -*- coding: utf-8 -*- # Copyright (c) 2013 - 2022 Detlev Offenbach <detlev@die-offenbachs.de> # """ Module implementing the PySide to PyQt (and vice versa) plug-in. """ import contextlib import os from PyQt6.QtCore import QObject, QTranslator from PyQt6.QtWidgets import QMenu from EricWidgets.EricApplication import ericApp # Start-Of-Header name = "PySide to PyQt (and vice versa) Plug-in" author = "Detlev Offenbach <detlev@die-offenbachs.de>" autoactivate = True deactivateable = True version = "1.0.0" className = "PySide2PyQtPlugin" packageName = "PySide2PyQt" shortDescription = "Convert PySide file to PyQt and vice versa" longDescription = ( """This plug-in implements a tool to convert a PySide2 file to PyQt5""" """ and vice versa or a PySide6 file to PyQt6 and vice versa. It works""" """ with the text of the current editor.""" ) needsRestart = False pyqtApi = 2 # End-Of-Header error = "" class PySide2PyQtPlugin(QObject): """ Class implementing the PySide to PyQt (and vice versa) plugin. """ def __init__(self, ui): """ Constructor @param ui reference to the user interface object @type UserInterface """ super().__init__(ui) self.__ui = ui self.__translator = None self.__loadTranslator() self.__initMenu() self.__editors = {} self.__mainActions = [] def activate(self): """ Public method to activate this plugin. @return tuple of None and activation status @rtype (None, bool) """ global error error = "" # clear previous error self.__ui.showMenu.connect(self.__populateMenu) menu = self.__ui.getMenu("plugin_tools") if menu is not None: if not menu.isEmpty(): act = menu.addSeparator() self.__mainActions.append(act) act = menu.addMenu(self.__menu) self.__mainActions.append(act) ericApp().getObject("ViewManager").editorOpenedEd.connect( self.__editorOpened) ericApp().getObject("ViewManager").editorClosedEd.connect( self.__editorClosed) for editor in ericApp().getObject("ViewManager").getOpenEditors(): self.__editorOpened(editor) return None, True def deactivate(self): """ Public method to deactivate this plugin. """ self.__ui.showMenu.disconnect(self.__populateMenu) menu = self.__ui.getMenu("plugin_tools") if menu is not None: for act in self.__mainActions: menu.removeAction(act) self.__mainActions = [] ericApp().getObject("ViewManager").editorOpenedEd.disconnect( self.__editorOpened) ericApp().getObject("ViewManager").editorClosedEd.disconnect( self.__editorClosed) for editor, acts in self.__editors.items(): editor.showMenu.disconnect(self.__editorShowMenu) menu = editor.getMenu("Tools") if menu is not None: for act in acts: menu.removeAction(act) self.__editors = {} 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__), "PySide2PyQt", "i18n") translation = "pyside2pyqt_{0}".format(loc) translator = QTranslator(None) loaded = translator.load(translation, locale_dir) if loaded: self.__translator = translator ericApp().installTranslator(self.__translator) else: print("Warning: translation file '{0}' could not be" " loaded.".format(translation)) print("Using default.") def __initMenu(self): """ Private method to initialize the menu. """ self.__menu = QMenu(self.tr("PySide to/from PyQt")) self.__menu.addAction(self.tr("PySide2 to PyQt5"), lambda: self.__pyside2Pyqt("pyside2", "pyqt5")) self.__menu.addAction(self.tr("PyQt5 to PySide2"), lambda: self.__pyqt2Pyside("pyqt5", "pyside2")) self.__menu.addSeparator() self.__menu.addAction(self.tr("PySide6 to PyQt6"), lambda: self.__pyside2Pyqt("pyside6", "pyqt6")) self.__menu.addAction(self.tr("PyQt6 to PySide6"), lambda: self.__pyqt2Pyside("pyqt6", "pyside6")) self.__menu.setEnabled(False) def __populateMenu(self, name, menu): """ Private slot to populate the tools menu with our entries. @param name name of the menu @type str @param menu reference to the menu to be populated @type QMenu """ if name not in ["Tools", "PluginTools"]: return editor = ericApp().getObject("ViewManager").activeWindow() if name == "Tools": if not menu.isEmpty(): menu.addSeparator() act = menu.addMenu(self.__menu) act.setEnabled(editor is not None) elif name == "PluginTools" and self.__mainActions: self.__mainActions[-1].setEnabled(editor is not None) def __editorOpened(self, editor): """ Private slot called, when a new editor was opened. @param editor reference to the new editor @type Editor """ menu = editor.getMenu("Tools") if menu is not None: self.__editors[editor] = [] if not menu.isEmpty(): act = menu.addSeparator() self.__editors[editor].append(act) act = menu.addMenu(self.__menu) self.__editors[editor].append(act) self.__menu.setEnabled(True) editor.showMenu.connect(self.__editorShowMenu) def __editorClosed(self, editor): """ Private slot called, when an editor was closed. @param editor reference to the editor @type Editor """ with contextlib.suppress(KeyError): del self.__editors[editor] if not self.__editors: self.__menu.setEnabled(False) def __editorShowMenu(self, menuName, menu, editor): """ Private slot called, when the the editor context menu or a submenu is about to be shown. @param menuName name of the menu to be shown @type str @param menu reference to the menu @type QMenu @param editor reference to the editor @type Editor """ if ( menuName == "Tools" and self.__menu.menuAction() not in menu.actions() ): # Re-add our menu self.__editors[editor] = [] if not menu.isEmpty(): act = menu.addSeparator() self.__editors[editor].append(act) act = menu.addMenu(self.__menu) self.__editors[editor].append(act) def __pyside2Pyqt(self, pyside, pyqt): """ Private slot to convert the code of the current editor from PySide to PyQt. @param pyside PySide variant (pyside2 or pyside6) @type str @param pyqt PyQt variant (pyqt5 or pyqt6) @type str """ editor = ericApp().getObject("ViewManager").activeWindow() if editor is None: return text = editor.text() if pyqt == "pyqt5" and pyside == "pyside2": newText = ( text .replace("PySide2", "PyQt5") .replace("Signal", "pyqtSignal") .replace("Slot", "pyqtSlot") .replace("Property", "pyqtProperty") .replace("pyside2-uic", "pyuic5") .replace("pyside2-rcc", "pyrcc5") .replace("pyside2-lupdate", "pylupdate5") ) elif pyqt == "pyqt6" and pyside == "pyside6": newText = ( text .replace("PySide6", "PyQt6") .replace("Signal", "pyqtSignal") .replace("Slot", "pyqtSlot") .replace("Property", "pyqtProperty") .replace("pyside6-uic", "pyuic6") .replace("pyside6-lupdate", "pylupdate6") ) else: return if newText != text: editor.beginUndoAction() editor.selectAll() editor.replaceSelectedText(newText) editor.endUndoAction() def __pyqt2Pyside(self, pyqt, pyside): """ Private slot to convert the code of the current editor from PyQt to PySide. @param pyqt PyQt variant (pyqt5 or pyqt6) @type str @param pyside PySide variant (pyside2 or pyside6) @type str """ editor = ericApp().getObject("ViewManager").activeWindow() if editor is None: return text = editor.text() if pyqt == "pyqt5" and pyside == "pyside2": newText = ( text .replace("PyQt5", "PySide2") .replace("pyqtSignal", "Signal") .replace("pyqtSlot", "Slot") .replace("pyqtProperty", "Property") .replace("pyuic5", "pyside2-uic") .replace("pyrcc5", "pyside2-rcc") .replace("pylupdate5", "pyside2-lupdate") ) elif pyqt == "pyqt6" and pyside == "pyside6": newText = ( text .replace("PyQt6", "PySide6") .replace("pyqtSignal", "Signal") .replace("pyqtSlot", "Slot") .replace("pyqtProperty", "Property") .replace("pyuic6", "pyside6-uic") .replace("pylupdate6", "pyside6-lupdate") ) else: return if newText != text: editor.beginUndoAction() editor.selectAll() editor.replaceSelectedText(newText) editor.endUndoAction() # # eflag: noqa = M801