Project/ProjectFormsBrowser.py

changeset 6597
dc668f774d3d
parent 6371
bc834bbc0251
child 6645
ad476851d7e0
diff -r 2d82cd481adc -r dc668f774d3d Project/ProjectFormsBrowser.py
--- a/Project/ProjectFormsBrowser.py	Wed Nov 21 19:26:59 2018 +0100
+++ b/Project/ProjectFormsBrowser.py	Sat Nov 24 15:37:04 2018 +0100
@@ -112,6 +112,10 @@
         ]
         
         self.compileProc = None
+        self.__uicompiler = ""
+        
+        self.project.projectClosed.connect(self.__resetUiCompiler)
+        self.project.projectPropertiesChanged.connect(self.__resetUiCompiler)
         
     def _createPopupMenus(self):
         """
@@ -137,6 +141,10 @@
                 self.__generateDialogCode)
             self.menu.addSeparator()
             self.menu.addAction(
+                self.tr('Configure uic Compiler'),
+                self.__configureUicCompiler)
+            self.menu.addSeparator()
+            self.menu.addAction(
                 self.tr('Open in Qt-Designer'), self.__openFile)
             self.menu.addAction(
                 self.tr('Open in Editor'), self.__openFileInEditor)
@@ -209,6 +217,10 @@
             self.backMenu.addAction(
                 self.tr('Compile all forms'), self.__compileAllForms)
             self.backMenu.addSeparator()
+            self.backMenu.addAction(
+                self.tr('Configure uic Compiler'),
+                self.__configureUicCompiler)
+            self.backMenu.addSeparator()
             self.backMenu.addAction(self.tr('New form...'), self.__newForm)
         else:
             if self.hooks["newForm"] is not None:
@@ -232,10 +244,14 @@
         self.multiMenu = QMenu(self)
         if self.project.getProjectType() in \
                 ["Qt4", "PyQt5", "E6Plugin", "PySide", "PySide2"]:
-            act = self.multiMenu.addAction(
+            self.multiMenu.addAction(
                 self.tr('Compile forms'), self.__compileSelectedForms)
             self.multiMenu.addSeparator()
             self.multiMenu.addAction(
+                self.tr('Configure uic Compiler'),
+                self.__configureUicCompiler)
+            self.multiMenu.addSeparator()
+            self.multiMenu.addAction(
                 self.tr('Open in Qt-Designer'), self.__openFile)
             self.multiMenu.addAction(
                 self.tr('Open in Editor'), self.__openFileInEditor)
@@ -277,6 +293,10 @@
             self.dirMenu.addAction(
                 self.tr('Compile all forms'), self.__compileAllForms)
             self.dirMenu.addSeparator()
+            self.dirMenu.addAction(
+                self.tr('Configure uic Compiler'),
+                self.__configureUicCompiler)
+            self.dirMenu.addSeparator()
         else:
             if self.hooks["compileAllForms"] is not None:
                 self.dirMenu.addAction(
@@ -322,6 +342,10 @@
             self.dirMultiMenu.addAction(
                 self.tr('Compile all forms'), self.__compileAllForms)
             self.dirMultiMenu.addSeparator()
+            self.dirMultiMenu.addAction(
+                self.tr('Configure uic Compiler'),
+                self.__configureUicCompiler)
+            self.dirMultiMenu.addSeparator()
         else:
             if self.hooks["compileAllForms"] is not None:
                 self.dirMultiMenu.addAction(
@@ -634,6 +658,58 @@
     ##  Methods to handle the various compile commands
     ###########################################################################
     
+    def __resetUiCompiler(self):
+        """
+        Private slot to reset the determined UI compiler executable.
+        """
+        self.__uicompiler = ""
+    
+    def __determineUiCompiler(self):
+        """
+        Private method to determine the UI compiler for the project.
+        """
+        self.__resetUiCompiler()
+        
+        if self.project.getProjectLanguage() in \
+                ["Python", "Python2", "Python3"]:
+            if self.project.getProjectType() in ["Qt4", ]:
+                self.__uicompiler = Utilities.generatePyQtToolPath(
+                    'pyuic4', ["py3uic4", "py2uic4"])
+            elif self.project.getProjectType() in ["PyQt5"]:
+                self.__uicompiler = Utilities.generatePyQtToolPath(
+                    'pyuic5', ["py3uic5", "py2uic5"])
+            elif self.project.getProjectType() in ["E6Plugin"]:
+                if PYQT_VERSION < 0x050000:
+                    self.__uicompiler = Utilities.generatePyQtToolPath(
+                        'pyuic4', ["py3uic4", "py2uic4"])
+                else:
+                    self.__uicompiler = Utilities.generatePyQtToolPath(
+                        'pyuic5', ["py3uic5", "py2uic5"])
+            elif self.project.getProjectType() == "PySide":
+                self.__uicompiler = \
+                    Utilities.generatePySideToolPath('pyside-uic', "1")
+            elif self.project.getProjectType() == "PySide2":
+                self.__uicompiler = \
+                    Utilities.generatePySideToolPath('pyside2-uic', "2")
+        elif self.project.getProjectLanguage() == "Ruby":
+            if self.project.getProjectType() == "Qt4":
+                self.__uicompiler = 'rbuic4'
+                if Utilities.isWindowsPlatform():
+                    self.__uicompiler = \
+                        Utilities.getWindowsExecutablePath(self.__uicompiler)
+    
+    def getUiCompiler(self):
+        """
+        Public method to get the UI compiler executable of the project.
+        
+        @return UI compiler executable
+        @rtype str
+        """
+        if not self.__uicompiler:
+            self.__determineUiCompiler()
+        
+        return self.__uicompiler
+    
     def __readStdout(self):
         """
         Private slot to handle the readyReadStandardOutput signal of the
@@ -659,7 +735,7 @@
         
         self.compileProc.setReadChannel(QProcess.StandardError)
         while self.compileProc and self.compileProc.canReadLine():
-            s = self.uicompiler + ': '
+            s = self.__uicompiler + ': '
             error = str(self.compileProc.readLine(),
                         ioEncoding, 'replace')
             s += error
@@ -742,38 +818,8 @@
         args = []
         self.buf = ""
         
-        if self.project.getProjectLanguage() in \
-                ["Python", "Python2", "Python3"]:
-            if self.project.getProjectType() in ["Qt4", ]:
-                self.uicompiler = Utilities.generatePyQtToolPath(
-                    'pyuic4', ["py3uic4", "py2uic4"])
-            elif self.project.getProjectType() in ["PyQt5"]:
-                self.uicompiler = Utilities.generatePyQtToolPath(
-                    'pyuic5', ["py3uic5", "py2uic5"])
-            elif self.project.getProjectType() in ["E6Plugin"]:
-                if PYQT_VERSION < 0x050000:
-                    self.uicompiler = Utilities.generatePyQtToolPath(
-                        'pyuic4', ["py3uic4", "py2uic4"])
-                else:
-                    self.uicompiler = Utilities.generatePyQtToolPath(
-                        'pyuic5', ["py3uic5", "py2uic5"])
-            elif self.project.getProjectType() == "PySide":
-                self.uicompiler = \
-                    Utilities.generatePySideToolPath('pyside-uic', "1")
-            elif self.project.getProjectType() == "PySide2":
-                self.uicompiler = \
-                    Utilities.generatePySideToolPath('pyside2-uic', "2")
-            else:
-                return None
-        elif self.project.getProjectLanguage() == "Ruby":
-            if self.project.getProjectType() == "Qt4":
-                self.uicompiler = 'rbuic4'
-                if Utilities.isWindowsPlatform():
-                    self.uicompiler = \
-                        Utilities.getWindowsExecutablePath(self.uicompiler)
-            else:
-                return None
-        else:
+        uicompiler = self.getUiCompiler()
+        if not uicompiler:
             return None
         
         ofn, ext = os.path.splitext(fn)
@@ -787,8 +833,24 @@
             indentWidth = Preferences.getQt("PyuicIndent")
             if indentWidth != self.PyuicIndentDefault:
                 args.append("--indent={0}".format(indentWidth))
-            if Preferences.getQt("PyuicFromImports"):
-                args.append("--from-imports")
+            
+            if self.project.getProjectType() in ["PySide", "PySide2"]:
+                # PySide and PySide2
+                if Preferences.getQt("PyuicFromImports"):
+                    args.append("--from-imports")
+            else:
+                # PyQt4 and PyQt5
+                if 'uic5' in uicompiler and \
+                   PYQT_VERSION >= 0x050600 and \
+                   self.project.pdata["UICPARAMS"]["Package"]:
+                    # only supported for PyQt5 >= 5.6 (April 2016)
+                    args.append("--import-from={0}".format(
+                        self.project.pdata["UICPARAMS"]["Package"]))
+                elif Preferences.getQt("PyuicFromImports"):
+                    args.append("--from-imports")
+                if self.project.pdata["UICPARAMS"]["RcSuffix"]:
+                    args.append("--resource-suffix={0}".format(
+                        self.project.pdata["UICPARAMS"]["RcSuffix"]))
         elif self.project.getProjectLanguage() == "Ruby":
             self.compiledFile = ofn + '.rb'
             args.append('-x')
@@ -799,7 +861,7 @@
         self.compileProc.readyReadStandardError.connect(self.__readStderr)
         
         self.noDialog = noDialog
-        self.compileProc.start(self.uicompiler, args)
+        self.compileProc.start(uicompiler, args)
         procStarted = self.compileProc.waitForStarted(5000)
         if procStarted:
             self.compileRunning = True
@@ -815,7 +877,7 @@
                 self.tr(
                     'Could not start {0}.<br>'
                     'Ensure that it is in the search path.'
-                ).format(self.uicompiler))
+                ).format(uicompiler))
             return None
         
     def __generateDialogCode(self):
@@ -996,6 +1058,33 @@
         Public slot used to handle the preferencesChanged signal.
         """
         ProjectBaseBrowser.handlePreferencesChanged(self)
+        
+        self.__resetUiCompiler()
+    
+    def __configureUicCompiler(self):
+        """
+        Private slot to configure some non-common uic compiler options.
+        """
+        from .UicCompilerOptionsDialog import UicCompilerOptionsDialog
+        
+        params = self.project.pdata["UICPARAMS"]
+        
+        if self.project.getProjectType() in ["Qt4", "PyQt5", "E6Plugin"]:
+            dlg = UicCompilerOptionsDialog(params, self.getUiCompiler())
+            if dlg.exec_() == QDialog.Accepted:
+                package, suffix = dlg.getData()
+                if package != params["Package"]:
+                    params["Package"] = package
+                    self.project.setDirty(True)
+                if suffix != params["RcSuffix"]:
+                    params["RcSuffix"] = suffix
+                    self.project.setDirty(True)
+        elif self.project.getProjectType() in ["PySide", "PySide2"]:
+            E5MessageBox.information(
+                self,
+                self.tr("Configure uic Compiler"),
+                self.tr("""No project specific uic compiler flags are"""
+                        """ supported for PySide or PySide2."""))
     
     ###########################################################################
     ## Support for hooks below

eric ide

mercurial