eric6/Project/ProjectFormsBrowser.py

branch
maintenance
changeset 8043
0acf98cd089a
parent 7924
8a96736d465e
parent 7959
44e15eda6506
child 8176
31965986ecd1
equal deleted inserted replaced
7991:866adc8c315b 8043:0acf98cd089a
23 ProjectBrowserDirectoryItem, ProjectBrowserFormType 23 ProjectBrowserDirectoryItem, ProjectBrowserFormType
24 ) 24 )
25 from .ProjectBaseBrowser import ProjectBaseBrowser 25 from .ProjectBaseBrowser import ProjectBaseBrowser
26 26
27 import UI.PixmapCache 27 import UI.PixmapCache
28 from UI.NotificationWidget import NotificationTypes
29
28 30
29 import Preferences 31 import Preferences
30 import Utilities 32 import Utilities
31 33
32 from eric6config import getConfig 34 from eric6config import getConfig
47 appendStderr = pyqtSignal(str) 49 appendStderr = pyqtSignal(str)
48 uipreview = pyqtSignal(str) 50 uipreview = pyqtSignal(str)
49 showMenu = pyqtSignal(str, QMenu) 51 showMenu = pyqtSignal(str, QMenu)
50 menusAboutToBeCreated = pyqtSignal() 52 menusAboutToBeCreated = pyqtSignal()
51 53
52 PyuicIndentDefault = 4 54 Pyuic5IndentDefault = 4
55 Pyuic6IndentDefault = 4
53 56
54 def __init__(self, project, parent=None): 57 def __init__(self, project, parent=None):
55 """ 58 """
56 Constructor 59 Constructor
57 60
121 self.dirMenuActions = [] 124 self.dirMenuActions = []
122 self.dirMultiMenuActions = [] 125 self.dirMultiMenuActions = []
123 126
124 self.menusAboutToBeCreated.emit() 127 self.menusAboutToBeCreated.emit()
125 128
129 projectType = self.project.getProjectType()
130
126 self.menu = QMenu(self) 131 self.menu = QMenu(self)
127 if self.project.getProjectType() in ["PyQt5", "E6Plugin", "PySide2"]: 132 if projectType in ["PyQt5", "PyQt6", "E6Plugin", "PySide2", "PySide6"]:
128 self.menu.addAction( 133 self.menu.addAction(
129 self.tr('Compile form'), self.__compileForm) 134 self.tr('Compile form'), self.__compileForm)
130 self.menu.addAction( 135 self.menu.addAction(
131 self.tr('Compile all forms'), 136 self.tr('Compile all forms'),
132 self.__compileAllForms) 137 self.__compileAllForms)
182 self.tr('Remove from project'), self._removeFile) 187 self.tr('Remove from project'), self._removeFile)
183 self.menuActions.append(act) 188 self.menuActions.append(act)
184 act = self.menu.addAction(self.tr('Delete'), self.__deleteFile) 189 act = self.menu.addAction(self.tr('Delete'), self.__deleteFile)
185 self.menuActions.append(act) 190 self.menuActions.append(act)
186 self.menu.addSeparator() 191 self.menu.addSeparator()
187 if self.project.getProjectType() in ["PyQt5", "E6Plugin", "PySide2"]: 192 if projectType in ["PyQt5", "PyQt6", "E6Plugin", "PySide2", "PySide6"]:
188 self.menu.addAction(self.tr('New form...'), self.__newForm) 193 self.menu.addAction(self.tr('New form...'), self.__newForm)
189 else: 194 else:
190 if self.hooks["newForm"] is not None: 195 if self.hooks["newForm"] is not None:
191 self.menu.addAction( 196 self.menu.addAction(
192 self.hooksMenuEntries.get( 197 self.hooksMenuEntries.get(
205 self.menu.addSeparator() 210 self.menu.addSeparator()
206 self.menu.addAction(self.tr('Configure...'), self._configure) 211 self.menu.addAction(self.tr('Configure...'), self._configure)
207 212
208 self.backMenu = QMenu(self) 213 self.backMenu = QMenu(self)
209 if ( 214 if (
210 self.project.getProjectType() in [ 215 projectType in [
211 "PyQt5", "E6Plugin", "PySide2" 216 "PyQt5", "PyQt6", "E6Plugin", "PySide2", "PySide6"
212 ] or 217 ] or self.hooks["compileAllForms"] is not None
213 self.hooks["compileAllForms"] is not None
214 ): 218 ):
215 self.backMenu.addAction( 219 self.backMenu.addAction(
216 self.tr('Compile all forms'), self.__compileAllForms) 220 self.tr('Compile all forms'), self.__compileAllForms)
217 self.backMenu.addSeparator() 221 self.backMenu.addSeparator()
218 self.__pyuicBackConfigAct = self.backMenu.addAction( 222 self.__pyuicBackConfigAct = self.backMenu.addAction(
238 self.backMenu.addAction(self.tr('Configure...'), self._configure) 242 self.backMenu.addAction(self.tr('Configure...'), self._configure)
239 self.backMenu.setEnabled(False) 243 self.backMenu.setEnabled(False)
240 244
241 # create the menu for multiple selected files 245 # create the menu for multiple selected files
242 self.multiMenu = QMenu(self) 246 self.multiMenu = QMenu(self)
243 if self.project.getProjectType() in ["PyQt5", "E6Plugin", "PySide2"]: 247 if projectType in ["PyQt5", "PyQt6", "E6Plugin", "PySide2", "PySide6"]:
244 self.multiMenu.addAction( 248 self.multiMenu.addAction(
245 self.tr('Compile forms'), self.__compileSelectedForms) 249 self.tr('Compile forms'), self.__compileSelectedForms)
246 self.multiMenu.addSeparator() 250 self.multiMenu.addSeparator()
247 self.__pyuicMultiConfigAct = self.multiMenu.addAction( 251 self.__pyuicMultiConfigAct = self.multiMenu.addAction(
248 self.tr('Configure uic Compiler'), 252 self.tr('Configure uic Compiler'),
283 self.tr('Collapse all directories'), self._collapseAllDirs) 287 self.tr('Collapse all directories'), self._collapseAllDirs)
284 self.multiMenu.addSeparator() 288 self.multiMenu.addSeparator()
285 self.multiMenu.addAction(self.tr('Configure...'), self._configure) 289 self.multiMenu.addAction(self.tr('Configure...'), self._configure)
286 290
287 self.dirMenu = QMenu(self) 291 self.dirMenu = QMenu(self)
288 if self.project.getProjectType() in ["PyQt5", "E6Plugin", "PySide2"]: 292 if projectType in ["PyQt5", "PyQt6", "E6Plugin", "PySide2", "PySide6"]:
289 self.dirMenu.addAction( 293 self.dirMenu.addAction(
290 self.tr('Compile all forms'), self.__compileAllForms) 294 self.tr('Compile all forms'), self.__compileAllForms)
291 self.dirMenu.addSeparator() 295 self.dirMenu.addSeparator()
292 self.__pyuicDirConfigAct = self.dirMenu.addAction( 296 self.__pyuicDirConfigAct = self.dirMenu.addAction(
293 self.tr('Configure uic Compiler'), 297 self.tr('Configure uic Compiler'),
306 self.dirMenuActions.append(act) 310 self.dirMenuActions.append(act)
307 act = self.dirMenu.addAction( 311 act = self.dirMenu.addAction(
308 self.tr('Delete'), self._deleteDirectory) 312 self.tr('Delete'), self._deleteDirectory)
309 self.dirMenuActions.append(act) 313 self.dirMenuActions.append(act)
310 self.dirMenu.addSeparator() 314 self.dirMenu.addSeparator()
311 if self.project.getProjectType() in ["PyQt5", "E6Plugin", "PySide2"]: 315 if projectType in ["PyQt5", "PyQt6", "E6Plugin", "PySide2", "PySide6"]:
312 self.dirMenu.addAction(self.tr('New form...'), self.__newForm) 316 self.dirMenu.addAction(self.tr('New form...'), self.__newForm)
313 else: 317 else:
314 if self.hooks["newForm"] is not None: 318 if self.hooks["newForm"] is not None:
315 self.dirMenu.addAction( 319 self.dirMenu.addAction(
316 self.hooksMenuEntries.get( 320 self.hooksMenuEntries.get(
330 self.tr('Collapse all directories'), self._collapseAllDirs) 334 self.tr('Collapse all directories'), self._collapseAllDirs)
331 self.dirMenu.addSeparator() 335 self.dirMenu.addSeparator()
332 self.dirMenu.addAction(self.tr('Configure...'), self._configure) 336 self.dirMenu.addAction(self.tr('Configure...'), self._configure)
333 337
334 self.dirMultiMenu = QMenu(self) 338 self.dirMultiMenu = QMenu(self)
335 if self.project.getProjectType() in ["PyQt5", "E6Plugin", "PySide2"]: 339 if projectType in ["PyQt5", "PyQt6", "E6Plugin", "PySide2", "PySide6"]:
336 self.dirMultiMenu.addAction( 340 self.dirMultiMenu.addAction(
337 self.tr('Compile all forms'), self.__compileAllForms) 341 self.tr('Compile all forms'), self.__compileAllForms)
338 self.dirMultiMenu.addSeparator() 342 self.dirMultiMenu.addSeparator()
339 self.__pyuicDirMultiConfigAct = self.dirMultiMenu.addAction( 343 self.__pyuicDirMultiConfigAct = self.dirMultiMenu.addAction(
340 self.tr('Configure uic Compiler'), 344 self.tr('Configure uic Compiler'),
375 @param coord the position of the mouse pointer (QPoint) 379 @param coord the position of the mouse pointer (QPoint)
376 """ 380 """
377 if not self.project.isOpen(): 381 if not self.project.isOpen():
378 return 382 return
379 383
380 enable = self.project.getProjectType() in ("PyQt5", "E6Plugin") 384 enable = (
385 self.project.getProjectType() in ("PyQt5", "PyQt6", "E6Plugin")
386 )
381 self.__pyuicConfigAct.setEnabled(enable) 387 self.__pyuicConfigAct.setEnabled(enable)
382 self.__pyuicMultiConfigAct.setEnabled(enable) 388 self.__pyuicMultiConfigAct.setEnabled(enable)
383 self.__pyuicDirConfigAct.setEnabled(enable) 389 self.__pyuicDirConfigAct.setEnabled(enable)
384 self.__pyuicDirMultiConfigAct.setEnabled(enable) 390 self.__pyuicDirMultiConfigAct.setEnabled(enable)
385 self.__pyuicBackConfigAct.setEnabled(enable) 391 self.__pyuicBackConfigAct.setEnabled(enable)
563 569
564 if self.hooks["newForm"] is not None: 570 if self.hooks["newForm"] is not None:
565 self.hooks["newForm"](path) 571 self.hooks["newForm"](path)
566 else: 572 else:
567 if self.project.getProjectType() in [ 573 if self.project.getProjectType() in [
568 "PyQt5", "E6Plugin", "PySide2" 574 "PyQt5", "PyQt6", "E6Plugin", "PySide2", "PySide6"
569 ]: 575 ]:
570 self.__newUiForm(path) 576 self.__newUiForm(path)
571 577
572 def __newUiForm(self, path): 578 def __newUiForm(self, path):
573 """ 579 """
679 685
680 if self.project.getProjectLanguage() == "Python3": 686 if self.project.getProjectLanguage() == "Python3":
681 if self.project.getProjectType() in ["PyQt5"]: 687 if self.project.getProjectType() in ["PyQt5"]:
682 self.__uicompiler = Utilities.generatePyQtToolPath( 688 self.__uicompiler = Utilities.generatePyQtToolPath(
683 'pyuic5', ["py3uic5"]) 689 'pyuic5', ["py3uic5"])
690 elif self.project.getProjectType() in ["PyQt6"]:
691 self.__uicompiler = Utilities.generatePyQtToolPath(
692 'pyuic6')
684 elif self.project.getProjectType() in ["E6Plugin"]: 693 elif self.project.getProjectType() in ["E6Plugin"]:
685 self.__uicompiler = Utilities.generatePyQtToolPath( 694 self.__uicompiler = Utilities.generatePyQtToolPath(
686 'pyuic5', ["py3uic5"]) 695 'pyuic5', ["py3uic5"])
687 elif self.project.getProjectType() == "PySide2": 696 elif self.project.getProjectType() == "PySide2":
688 self.__uicompiler = Utilities.generatePySideToolPath( 697 self.__uicompiler = Utilities.generatePySideToolPath(
689 'pyside2-uic') 698 'pyside2-uic', variant=2)
699 elif self.project.getProjectType() == "PySide6":
700 self.__uicompiler = Utilities.generatePySideToolPath(
701 'pyside6-uic', variant=6)
690 702
691 def getUiCompiler(self): 703 def getUiCompiler(self):
692 """ 704 """
693 Public method to get the UI compiler executable of the project. 705 Public method to get the UI compiler executable of the project.
694 706
701 return self.__uicompiler 713 return self.__uicompiler
702 714
703 def __readStdout(self): 715 def __readStdout(self):
704 """ 716 """
705 Private slot to handle the readyReadStandardOutput signal of the 717 Private slot to handle the readyReadStandardOutput signal of the
706 pyuic5/pyside2-uic process. 718 pyuic5/pyuic6/pyside2-uic/pyside6-uic process.
707 """ 719 """
708 if self.compileProc is None: 720 if self.compileProc is None:
709 return 721 return
710 self.compileProc.setReadChannel(QProcess.StandardOutput) 722 self.compileProc.setReadChannel(QProcess.StandardOutput)
711 723
714 "utf-8", 'replace') 726 "utf-8", 'replace')
715 727
716 def __readStderr(self): 728 def __readStderr(self):
717 """ 729 """
718 Private slot to handle the readyReadStandardError signal of the 730 Private slot to handle the readyReadStandardError signal of the
719 pyuic5/pyside2-uic process. 731 pyuic5/pyuic6/pyside2-uic/pyside6-uic process.
720 """ 732 """
721 if self.compileProc is None: 733 if self.compileProc is None:
722 return 734 return
723 735
724 ioEncoding = Preferences.getSystem("IOEncoding") 736 ioEncoding = Preferences.getSystem("IOEncoding")
751 with open(ofn, "w", encoding="utf-8", newline=newline) as f: 763 with open(ofn, "w", encoding="utf-8", newline=newline) as f:
752 for line in self.buf.splitlines(): 764 for line in self.buf.splitlines():
753 f.write(line + "\n") 765 f.write(line + "\n")
754 if self.compiledFile not in self.project.pdata["SOURCES"]: 766 if self.compiledFile not in self.project.pdata["SOURCES"]:
755 self.project.appendFile(ofn) 767 self.project.appendFile(ofn)
756 if not self.noDialog and not ui.notificationsEnabled():
757 E5MessageBox.information(
758 self,
759 self.tr("Form Compilation"),
760 self.tr("The compilation of the form file"
761 " was successful."))
762 else:
763 ui.showNotification(
764 UI.PixmapCache.getPixmap("designer48"),
765 self.tr("Form Compilation"),
766 self.tr("The compilation of the form file"
767 " was successful."))
768 self.project.projectFormCompiled.emit(self.compiledFile)
769 except OSError as msg:
770 if not self.noDialog:
771 E5MessageBox.information(
772 self,
773 self.tr("Form Compilation"),
774 self.tr(
775 "<p>The compilation of the form file failed.</p>"
776 "<p>Reason: {0}</p>").format(str(msg)))
777 else:
778 ui.showNotification(
779 UI.PixmapCache.getPixmap("designer48"),
780 self.tr("Form Compilation"),
781 self.tr(
782 "<p>The compilation of the form file failed.</p>"
783 "<p>Reason: {0}</p>").format(str(msg)))
784 else:
785 if not self.noDialog:
786 E5MessageBox.information(
787 self,
788 self.tr("Form Compilation"),
789 self.tr("The compilation of the form file failed."))
790 else:
791 ui.showNotification( 768 ui.showNotification(
792 UI.PixmapCache.getPixmap("designer48"), 769 UI.PixmapCache.getPixmap("designer48"),
793 self.tr("Form Compilation"), 770 self.tr("Form Compilation"),
794 self.tr("The compilation of the form file failed.")) 771 self.tr("The compilation of the form file"
772 " was successful."))
773 self.project.projectFormCompiled.emit(self.compiledFile)
774 except OSError as msg:
775 ui.showNotification(
776 UI.PixmapCache.getPixmap("designer48"),
777 self.tr("Form Compilation"),
778 self.tr(
779 "<p>The compilation of the form file failed.</p>"
780 "<p>Reason: {0}</p>").format(str(msg)),
781 kind=NotificationTypes.Critical,
782 timeout=0)
783 else:
784 ui.showNotification(
785 UI.PixmapCache.getPixmap("designer48"),
786 self.tr("Form Compilation"),
787 self.tr("The compilation of the form file failed."),
788 kind=NotificationTypes.Critical,
789 timeout=0)
795 self.compileProc = None 790 self.compileProc = None
796 791
797 def __compileUI(self, fn, noDialog=False, progress=None): 792 def __compileUI(self, fn, noDialog=False, progress=None):
798 """ 793 """
799 Private method to compile a .ui file to a .py/.rb file. 794 Private method to compile a .ui file to a .py/.rb file.
820 815
821 if self.project.getProjectType() == "PySide2": 816 if self.project.getProjectType() == "PySide2":
822 # PySide2 817 # PySide2
823 if Preferences.getQt("PySide2FromImports"): 818 if Preferences.getQt("PySide2FromImports"):
824 args.append("--from-imports") 819 args.append("--from-imports")
820 elif self.project.getProjectType() == "PySide6":
821 # PySide6
822 if Preferences.getQt("PySide6FromImports"):
823 args.append("--from-imports")
824 elif self.project.getProjectType() == "PyQt6":
825 # PyQt6
826 if Preferences.getQt("Pyuic6Execute"):
827 args.append("-x")
828 indentWidth = Preferences.getQt("Pyuic6Indent")
829 if indentWidth != self.Pyuic6IndentDefault:
830 args.append("--indent={0}".format(indentWidth))
825 else: 831 else:
826 # PyQt5 832 # PyQt5
827 if Preferences.getQt("PyuicExecute"): 833 if Preferences.getQt("PyuicExecute"):
828 args.append("-x") 834 args.append("-x")
829 indentWidth = Preferences.getQt("PyuicIndent") 835 indentWidth = Preferences.getQt("PyuicIndent")
830 if indentWidth != self.PyuicIndentDefault: 836 if indentWidth != self.Pyuic5IndentDefault:
831 args.append("--indent={0}".format(indentWidth)) 837 args.append("--indent={0}".format(indentWidth))
832 if ( 838 if (
833 'uic5' in uicompiler and 839 'uic5' in uicompiler and
834 self.project.pdata["UICPARAMS"]["Package"] 840 self.project.pdata["UICPARAMS"]["Package"]
835 ): 841 ):
985 """ 991 """
986 if self.hooks["compileChangedForms"] is not None: 992 if self.hooks["compileChangedForms"] is not None:
987 self.hooks["compileChangedForms"](self.project.pdata["FORMS"]) 993 self.hooks["compileChangedForms"](self.project.pdata["FORMS"])
988 else: 994 else:
989 if self.project.getProjectType() not in [ 995 if self.project.getProjectType() not in [
990 "PyQt5", "E6Plugin", "PySide2" 996 "PyQt5", "PyQt6", "E6Plugin", "PySide2", "PySide6"
991 ]: 997 ]:
992 # ignore the request for non Qt GUI projects 998 # ignore the request for non Qt GUI projects
993 return 999 return
994 1000
995 progress = E5ProgressDialog( 1001 progress = E5ProgressDialog(
1059 """ 1065 """
1060 from .UicCompilerOptionsDialog import UicCompilerOptionsDialog 1066 from .UicCompilerOptionsDialog import UicCompilerOptionsDialog
1061 1067
1062 params = self.project.pdata["UICPARAMS"] 1068 params = self.project.pdata["UICPARAMS"]
1063 1069
1064 if self.project.getProjectType() in ["PyQt5", "E6Plugin"]: 1070 if self.project.getProjectType() in ["PyQt5", "PyQt6", "E6Plugin"]:
1065 dlg = UicCompilerOptionsDialog(params, self.getUiCompiler()) 1071 dlg = UicCompilerOptionsDialog(params, self.getUiCompiler())
1066 if dlg.exec() == QDialog.Accepted: 1072 if dlg.exec() == QDialog.Accepted:
1067 package, suffix, root = dlg.getData() 1073 package, suffix, root = dlg.getData()
1068 if package != params["Package"]: 1074 if package != params["Package"]:
1069 params["Package"] = package 1075 params["Package"] = package

eric ide

mercurial