38 |
38 |
39 class PySide2PyQtPlugin(QObject): |
39 class PySide2PyQtPlugin(QObject): |
40 """ |
40 """ |
41 Class implementing the PySide to PyQt (and vice versa) plugin. |
41 Class implementing the PySide to PyQt (and vice versa) plugin. |
42 """ |
42 """ |
|
43 |
43 def __init__(self, ui): |
44 def __init__(self, ui): |
44 """ |
45 """ |
45 Constructor |
46 Constructor |
46 |
47 |
47 @param ui reference to the user interface object |
48 @param ui reference to the user interface object |
48 @type UserInterface |
49 @type UserInterface |
49 """ |
50 """ |
50 super().__init__(ui) |
51 super().__init__(ui) |
51 self.__ui = ui |
52 self.__ui = ui |
52 |
53 |
53 self.__translator = None |
54 self.__translator = None |
54 self.__loadTranslator() |
55 self.__loadTranslator() |
55 |
56 |
56 self.__initMenu() |
57 self.__initMenu() |
57 |
58 |
58 self.__editors = {} |
59 self.__editors = {} |
59 self.__mainActions = [] |
60 self.__mainActions = [] |
60 |
61 |
61 def activate(self): |
62 def activate(self): |
62 """ |
63 """ |
63 Public method to activate this plugin. |
64 Public method to activate this plugin. |
64 |
65 |
65 @return tuple of None and activation status |
66 @return tuple of None and activation status |
66 @rtype (None, bool) |
67 @rtype (None, bool) |
67 """ |
68 """ |
68 global error |
69 global error |
69 error = "" # clear previous error |
70 error = "" # clear previous error |
70 |
71 |
71 self.__ui.showMenu.connect(self.__populateMenu) |
72 self.__ui.showMenu.connect(self.__populateMenu) |
72 |
73 |
73 menu = self.__ui.getMenu("plugin_tools") |
74 menu = self.__ui.getMenu("plugin_tools") |
74 if menu is not None: |
75 if menu is not None: |
75 if not menu.isEmpty(): |
76 if not menu.isEmpty(): |
76 act = menu.addSeparator() |
77 act = menu.addSeparator() |
77 self.__mainActions.append(act) |
78 self.__mainActions.append(act) |
78 act = menu.addMenu(self.__menu) |
79 act = menu.addMenu(self.__menu) |
79 self.__mainActions.append(act) |
80 self.__mainActions.append(act) |
80 |
81 |
81 ericApp().getObject("ViewManager").editorOpenedEd.connect( |
82 ericApp().getObject("ViewManager").editorOpenedEd.connect(self.__editorOpened) |
82 self.__editorOpened) |
83 ericApp().getObject("ViewManager").editorClosedEd.connect(self.__editorClosed) |
83 ericApp().getObject("ViewManager").editorClosedEd.connect( |
84 |
84 self.__editorClosed) |
|
85 |
|
86 for editor in ericApp().getObject("ViewManager").getOpenEditors(): |
85 for editor in ericApp().getObject("ViewManager").getOpenEditors(): |
87 self.__editorOpened(editor) |
86 self.__editorOpened(editor) |
88 |
87 |
89 return None, True |
88 return None, True |
90 |
89 |
91 def deactivate(self): |
90 def deactivate(self): |
92 """ |
91 """ |
93 Public method to deactivate this plugin. |
92 Public method to deactivate this plugin. |
94 """ |
93 """ |
95 self.__ui.showMenu.disconnect(self.__populateMenu) |
94 self.__ui.showMenu.disconnect(self.__populateMenu) |
96 |
95 |
97 menu = self.__ui.getMenu("plugin_tools") |
96 menu = self.__ui.getMenu("plugin_tools") |
98 if menu is not None: |
97 if menu is not None: |
99 for act in self.__mainActions: |
98 for act in self.__mainActions: |
100 menu.removeAction(act) |
99 menu.removeAction(act) |
101 self.__mainActions = [] |
100 self.__mainActions = [] |
102 |
101 |
103 ericApp().getObject("ViewManager").editorOpenedEd.disconnect( |
102 ericApp().getObject("ViewManager").editorOpenedEd.disconnect( |
104 self.__editorOpened) |
103 self.__editorOpened |
|
104 ) |
105 ericApp().getObject("ViewManager").editorClosedEd.disconnect( |
105 ericApp().getObject("ViewManager").editorClosedEd.disconnect( |
106 self.__editorClosed) |
106 self.__editorClosed |
107 |
107 ) |
|
108 |
108 for editor, acts in self.__editors.items(): |
109 for editor, acts in self.__editors.items(): |
109 editor.showMenu.disconnect(self.__editorShowMenu) |
110 editor.showMenu.disconnect(self.__editorShowMenu) |
110 menu = editor.getMenu("Tools") |
111 menu = editor.getMenu("Tools") |
111 if menu is not None: |
112 if menu is not None: |
112 for act in acts: |
113 for act in acts: |
113 menu.removeAction(act) |
114 menu.removeAction(act) |
114 self.__editors = {} |
115 self.__editors = {} |
115 |
116 |
116 def __loadTranslator(self): |
117 def __loadTranslator(self): |
117 """ |
118 """ |
118 Private method to load the translation file. |
119 Private method to load the translation file. |
119 """ |
120 """ |
120 if self.__ui is not None: |
121 if self.__ui is not None: |
121 loc = self.__ui.getLocale() |
122 loc = self.__ui.getLocale() |
122 if loc and loc != "C": |
123 if loc and loc != "C": |
123 locale_dir = os.path.join( |
124 locale_dir = os.path.join( |
124 os.path.dirname(__file__), "PySide2PyQt", "i18n") |
125 os.path.dirname(__file__), "PySide2PyQt", "i18n" |
|
126 ) |
125 translation = "pyside2pyqt_{0}".format(loc) |
127 translation = "pyside2pyqt_{0}".format(loc) |
126 translator = QTranslator(None) |
128 translator = QTranslator(None) |
127 loaded = translator.load(translation, locale_dir) |
129 loaded = translator.load(translation, locale_dir) |
128 if loaded: |
130 if loaded: |
129 self.__translator = translator |
131 self.__translator = translator |
130 ericApp().installTranslator(self.__translator) |
132 ericApp().installTranslator(self.__translator) |
131 else: |
133 else: |
132 print("Warning: translation file '{0}' could not be" |
134 print( |
133 " loaded.".format(translation)) |
135 "Warning: translation file '{0}' could not be" |
|
136 " loaded.".format(translation) |
|
137 ) |
134 print("Using default.") |
138 print("Using default.") |
135 |
139 |
136 def __initMenu(self): |
140 def __initMenu(self): |
137 """ |
141 """ |
138 Private method to initialize the menu. |
142 Private method to initialize the menu. |
139 """ |
143 """ |
140 self.__menu = QMenu(self.tr("PySide to/from PyQt")) |
144 self.__menu = QMenu(self.tr("PySide to/from PyQt")) |
141 self.__menu.addAction(self.tr("PySide2 to PyQt5"), |
145 self.__menu.addAction( |
142 lambda: self.__pyside2Pyqt("pyside2", "pyqt5")) |
146 self.tr("PySide2 to PyQt5"), lambda: self.__pyside2Pyqt("pyside2", "pyqt5") |
143 self.__menu.addAction(self.tr("PyQt5 to PySide2"), |
147 ) |
144 lambda: self.__pyqt2Pyside("pyqt5", "pyside2")) |
148 self.__menu.addAction( |
|
149 self.tr("PyQt5 to PySide2"), lambda: self.__pyqt2Pyside("pyqt5", "pyside2") |
|
150 ) |
145 self.__menu.addSeparator() |
151 self.__menu.addSeparator() |
146 self.__menu.addAction(self.tr("PySide6 to PyQt6"), |
152 self.__menu.addAction( |
147 lambda: self.__pyside2Pyqt("pyside6", "pyqt6")) |
153 self.tr("PySide6 to PyQt6"), lambda: self.__pyside2Pyqt("pyside6", "pyqt6") |
148 self.__menu.addAction(self.tr("PyQt6 to PySide6"), |
154 ) |
149 lambda: self.__pyqt2Pyside("pyqt6", "pyside6")) |
155 self.__menu.addAction( |
|
156 self.tr("PyQt6 to PySide6"), lambda: self.__pyqt2Pyside("pyqt6", "pyside6") |
|
157 ) |
150 self.__menu.setEnabled(False) |
158 self.__menu.setEnabled(False) |
151 |
159 |
152 def __populateMenu(self, name, menu): |
160 def __populateMenu(self, name, menu): |
153 """ |
161 """ |
154 Private slot to populate the tools menu with our entries. |
162 Private slot to populate the tools menu with our entries. |
155 |
163 |
156 @param name name of the menu |
164 @param name name of the menu |
157 @type str |
165 @type str |
158 @param menu reference to the menu to be populated |
166 @param menu reference to the menu to be populated |
159 @type QMenu |
167 @type QMenu |
160 """ |
168 """ |
161 if name not in ["Tools", "PluginTools"]: |
169 if name not in ["Tools", "PluginTools"]: |
162 return |
170 return |
163 |
171 |
164 editor = ericApp().getObject("ViewManager").activeWindow() |
172 editor = ericApp().getObject("ViewManager").activeWindow() |
165 |
173 |
166 if name == "Tools": |
174 if name == "Tools": |
167 if not menu.isEmpty(): |
175 if not menu.isEmpty(): |
168 menu.addSeparator() |
176 menu.addSeparator() |
169 act = menu.addMenu(self.__menu) |
177 act = menu.addMenu(self.__menu) |
170 act.setEnabled(editor is not None) |
178 act.setEnabled(editor is not None) |
171 elif name == "PluginTools" and self.__mainActions: |
179 elif name == "PluginTools" and self.__mainActions: |
172 self.__mainActions[-1].setEnabled(editor is not None) |
180 self.__mainActions[-1].setEnabled(editor is not None) |
173 |
181 |
174 def __editorOpened(self, editor): |
182 def __editorOpened(self, editor): |
175 """ |
183 """ |
176 Private slot called, when a new editor was opened. |
184 Private slot called, when a new editor was opened. |
177 |
185 |
178 @param editor reference to the new editor |
186 @param editor reference to the new editor |
179 @type Editor |
187 @type Editor |
180 """ |
188 """ |
181 menu = editor.getMenu("Tools") |
189 menu = editor.getMenu("Tools") |
182 if menu is not None: |
190 if menu is not None: |
186 self.__editors[editor].append(act) |
194 self.__editors[editor].append(act) |
187 act = menu.addMenu(self.__menu) |
195 act = menu.addMenu(self.__menu) |
188 self.__editors[editor].append(act) |
196 self.__editors[editor].append(act) |
189 self.__menu.setEnabled(True) |
197 self.__menu.setEnabled(True) |
190 editor.showMenu.connect(self.__editorShowMenu) |
198 editor.showMenu.connect(self.__editorShowMenu) |
191 |
199 |
192 def __editorClosed(self, editor): |
200 def __editorClosed(self, editor): |
193 """ |
201 """ |
194 Private slot called, when an editor was closed. |
202 Private slot called, when an editor was closed. |
195 |
203 |
196 @param editor reference to the editor |
204 @param editor reference to the editor |
197 @type Editor |
205 @type Editor |
198 """ |
206 """ |
199 with contextlib.suppress(KeyError): |
207 with contextlib.suppress(KeyError): |
200 del self.__editors[editor] |
208 del self.__editors[editor] |
201 if not self.__editors: |
209 if not self.__editors: |
202 self.__menu.setEnabled(False) |
210 self.__menu.setEnabled(False) |
203 |
211 |
204 def __editorShowMenu(self, menuName, menu, editor): |
212 def __editorShowMenu(self, menuName, menu, editor): |
205 """ |
213 """ |
206 Private slot called, when the the editor context menu or a submenu is |
214 Private slot called, when the the editor context menu or a submenu is |
207 about to be shown. |
215 about to be shown. |
208 |
216 |
209 @param menuName name of the menu to be shown |
217 @param menuName name of the menu to be shown |
210 @type str |
218 @type str |
211 @param menu reference to the menu |
219 @param menu reference to the menu |
212 @type QMenu |
220 @type QMenu |
213 @param editor reference to the editor |
221 @param editor reference to the editor |
214 @type Editor |
222 @type Editor |
215 """ |
223 """ |
216 if ( |
224 if menuName == "Tools" and self.__menu.menuAction() not in menu.actions(): |
217 menuName == "Tools" and |
|
218 self.__menu.menuAction() not in menu.actions() |
|
219 ): |
|
220 # Re-add our menu |
225 # Re-add our menu |
221 self.__editors[editor] = [] |
226 self.__editors[editor] = [] |
222 if not menu.isEmpty(): |
227 if not menu.isEmpty(): |
223 act = menu.addSeparator() |
228 act = menu.addSeparator() |
224 self.__editors[editor].append(act) |
229 self.__editors[editor].append(act) |
225 act = menu.addMenu(self.__menu) |
230 act = menu.addMenu(self.__menu) |
226 self.__editors[editor].append(act) |
231 self.__editors[editor].append(act) |
227 |
232 |
228 def __pyside2Pyqt(self, pyside, pyqt): |
233 def __pyside2Pyqt(self, pyside, pyqt): |
229 """ |
234 """ |
230 Private slot to convert the code of the current editor from PySide |
235 Private slot to convert the code of the current editor from PySide |
231 to PyQt. |
236 to PyQt. |
232 |
237 |
233 @param pyside PySide variant (pyside2 or pyside6) |
238 @param pyside PySide variant (pyside2 or pyside6) |
234 @type str |
239 @type str |
235 @param pyqt PyQt variant (pyqt5 or pyqt6) |
240 @param pyqt PyQt variant (pyqt5 or pyqt6) |
236 @type str |
241 @type str |
237 """ |
242 """ |
238 editor = ericApp().getObject("ViewManager").activeWindow() |
243 editor = ericApp().getObject("ViewManager").activeWindow() |
239 if editor is None: |
244 if editor is None: |
240 return |
245 return |
241 |
246 |
242 text = editor.text() |
247 text = editor.text() |
243 if pyqt == "pyqt5" and pyside == "pyside2": |
248 if pyqt == "pyqt5" and pyside == "pyside2": |
244 newText = ( |
249 newText = ( |
245 text |
250 text.replace("PySide2", "PyQt5") |
246 .replace("PySide2", "PyQt5") |
|
247 .replace("Signal", "pyqtSignal") |
251 .replace("Signal", "pyqtSignal") |
248 .replace("Slot", "pyqtSlot") |
252 .replace("Slot", "pyqtSlot") |
249 .replace("Property", "pyqtProperty") |
253 .replace("Property", "pyqtProperty") |
250 .replace("pyside2-uic", "pyuic5") |
254 .replace("pyside2-uic", "pyuic5") |
251 .replace("pyside2-rcc", "pyrcc5") |
255 .replace("pyside2-rcc", "pyrcc5") |
252 .replace("pyside2-lupdate", "pylupdate5") |
256 .replace("pyside2-lupdate", "pylupdate5") |
253 ) |
257 ) |
254 elif pyqt == "pyqt6" and pyside == "pyside6": |
258 elif pyqt == "pyqt6" and pyside == "pyside6": |
255 newText = ( |
259 newText = ( |
256 text |
260 text.replace("PySide6", "PyQt6") |
257 .replace("PySide6", "PyQt6") |
|
258 .replace("Signal", "pyqtSignal") |
261 .replace("Signal", "pyqtSignal") |
259 .replace("Slot", "pyqtSlot") |
262 .replace("Slot", "pyqtSlot") |
260 .replace("Property", "pyqtProperty") |
263 .replace("Property", "pyqtProperty") |
261 .replace("pyside6-uic", "pyuic6") |
264 .replace("pyside6-uic", "pyuic6") |
262 .replace("pyside6-lupdate", "pylupdate6") |
265 .replace("pyside6-lupdate", "pylupdate6") |
263 ) |
266 ) |
264 else: |
267 else: |
265 return |
268 return |
266 |
269 |
267 if newText != text: |
270 if newText != text: |
268 editor.beginUndoAction() |
271 editor.beginUndoAction() |
269 editor.selectAll() |
272 editor.selectAll() |
270 editor.replaceSelectedText(newText) |
273 editor.replaceSelectedText(newText) |
271 editor.endUndoAction() |
274 editor.endUndoAction() |
272 |
275 |
273 def __pyqt2Pyside(self, pyqt, pyside): |
276 def __pyqt2Pyside(self, pyqt, pyside): |
274 """ |
277 """ |
275 Private slot to convert the code of the current editor from PyQt |
278 Private slot to convert the code of the current editor from PyQt |
276 to PySide. |
279 to PySide. |
277 |
280 |
278 @param pyqt PyQt variant (pyqt5 or pyqt6) |
281 @param pyqt PyQt variant (pyqt5 or pyqt6) |
279 @type str |
282 @type str |
280 @param pyside PySide variant (pyside2 or pyside6) |
283 @param pyside PySide variant (pyside2 or pyside6) |
281 @type str |
284 @type str |
282 """ |
285 """ |
283 editor = ericApp().getObject("ViewManager").activeWindow() |
286 editor = ericApp().getObject("ViewManager").activeWindow() |
284 if editor is None: |
287 if editor is None: |
285 return |
288 return |
286 |
289 |
287 text = editor.text() |
290 text = editor.text() |
288 if pyqt == "pyqt5" and pyside == "pyside2": |
291 if pyqt == "pyqt5" and pyside == "pyside2": |
289 newText = ( |
292 newText = ( |
290 text |
293 text.replace("PyQt5", "PySide2") |
291 .replace("PyQt5", "PySide2") |
|
292 .replace("pyqtSignal", "Signal") |
294 .replace("pyqtSignal", "Signal") |
293 .replace("pyqtSlot", "Slot") |
295 .replace("pyqtSlot", "Slot") |
294 .replace("pyqtProperty", "Property") |
296 .replace("pyqtProperty", "Property") |
295 .replace("pyuic5", "pyside2-uic") |
297 .replace("pyuic5", "pyside2-uic") |
296 .replace("pyrcc5", "pyside2-rcc") |
298 .replace("pyrcc5", "pyside2-rcc") |
297 .replace("pylupdate5", "pyside2-lupdate") |
299 .replace("pylupdate5", "pyside2-lupdate") |
298 ) |
300 ) |
299 elif pyqt == "pyqt6" and pyside == "pyside6": |
301 elif pyqt == "pyqt6" and pyside == "pyside6": |
300 newText = ( |
302 newText = ( |
301 text |
303 text.replace("PyQt6", "PySide6") |
302 .replace("PyQt6", "PySide6") |
|
303 .replace("pyqtSignal", "Signal") |
304 .replace("pyqtSignal", "Signal") |
304 .replace("pyqtSlot", "Slot") |
305 .replace("pyqtSlot", "Slot") |
305 .replace("pyqtProperty", "Property") |
306 .replace("pyqtProperty", "Property") |
306 .replace("pyuic6", "pyside6-uic") |
307 .replace("pyuic6", "pyside6-uic") |
307 .replace("pylupdate6", "pyside6-lupdate") |
308 .replace("pylupdate6", "pyside6-lupdate") |
308 ) |
309 ) |
309 else: |
310 else: |
310 return |
311 return |
311 |
312 |
312 if newText != text: |
313 if newText != text: |
313 editor.beginUndoAction() |
314 editor.beginUndoAction() |
314 editor.selectAll() |
315 editor.selectAll() |
315 editor.replaceSelectedText(newText) |
316 editor.replaceSelectedText(newText) |
316 editor.endUndoAction() |
317 editor.endUndoAction() |
317 |
318 |
|
319 |
318 # |
320 # |
319 # eflag: noqa = M801 |
321 # eflag: noqa = M801 |