Project/ProjectTranslationsBrowser.py

branch
Py2 comp.
changeset 2847
1843ef6e2656
parent 2791
a9577f248f04
parent 2803
282752ecd0fc
child 3057
10516539f238
equal deleted inserted replaced
2846:b852fe4d153a 2847:1843ef6e2656
75 """<b>Project Translations Browser</b>""" 75 """<b>Project Translations Browser</b>"""
76 """<p>This allows to easily see all translations contained in the current""" 76 """<p>This allows to easily see all translations contained in the current"""
77 """ project. Several actions can be executed via the context menu.</p>""" 77 """ project. Several actions can be executed via the context menu.</p>"""
78 )) 78 ))
79 79
80 self.lreleaseProc = None 80 self.__lreleaseProcesses = []
81 self.__pylupdateProcesses = []
81 self.lreleaseProcRunning = False 82 self.lreleaseProcRunning = False
82 self.pylupdateProc = None
83 self.pylupdateProcRunning = False 83 self.pylupdateProcRunning = False
84 self.tmpProject = [] 84 self.__tmpProjects = []
85 85
86 def _createPopupMenus(self): 86 def _createPopupMenus(self):
87 """ 87 """
88 Protected overloaded method to generate the popup menu. 88 Protected overloaded method to generate the popup menu.
89 """ 89 """
771 else: 771 else:
772 pf.write('{0} {1}{2}'.format( 772 pf.write('{0} {1}{2}'.format(
773 list[0].replace(os.sep, '/'), "\n", "\n")) 773 list[0].replace(os.sep, '/'), "\n", "\n"))
774 774
775 pf.close() 775 pf.close()
776 self.tmpProject.append(outFile) 776 self.__tmpProjects.append(outFile)
777 except IOError: 777 except IOError:
778 E5MessageBox.critical(self, 778 E5MessageBox.critical(self,
779 self.trUtf8("Write temporary project file"), 779 self.trUtf8("Write temporary project file"),
780 self.trUtf8("<p>The temporary project file <b>{0}</b> could not" 780 self.trUtf8("<p>The temporary project file <b>{0}</b> could not"
781 " be written.</p>").format(outFile)) 781 " be written.</p>").format(outFile))
782 self.tmpProject = [] 782
783 return False 783 if len(self.__tmpProjects) == 0:
784 return False
784 785
785 return True 786 return True
786 787
787 def __readStdoutLupdate(self): 788 def __readStdoutLupdate(self):
788 """ 789 """
789 Private slot to handle the readyReadStandardOutput signal of the 790 Private slot to handle the readyReadStandardOutput signal of the
790 pylupdate process. 791 pylupdate process.
791 """ 792 """
792 if self.pylupdateProc is not None: 793 proc = self.sender()
793 self.__readStdout(self.pylupdateProc, '{0}: '.format(self.pylupdate)) 794 if proc is not None:
795 self.__readStdout(proc, '{0}: '.format(self.pylupdate))
794 else: 796 else:
795 return 797 return
796 798
797 def __readStdoutLrelease(self): 799 def __readStdoutLrelease(self):
798 """ 800 """
799 Private slot to handle the readyReadStandardOutput signal of the 801 Private slot to handle the readyReadStandardOutput signal of the
800 lrelease process. 802 lrelease process.
801 """ 803 """
802 if self.lreleaseProc is not None: 804 proc = self.sender()
803 self.__readStdout(self.lreleaseProc, 'lrelease: ') 805 if proc is not None:
806 self.__readStdout(proc, 'lrelease: ')
804 else: 807 else:
805 return 808 return
806 809
807 def __readStdout(self, proc, ps): 810 def __readStdout(self, proc, ps):
808 """ 811 """
823 def __readStderrLupdate(self): 826 def __readStderrLupdate(self):
824 """ 827 """
825 Private slot to handle the readyReadStandardError signal of the 828 Private slot to handle the readyReadStandardError signal of the
826 pylupdate process. 829 pylupdate process.
827 """ 830 """
828 if self.pylupdateProc is not None: 831 proc = self.sender()
829 self.__readStderr(self.pylupdateProc, '{0}: '.format(self.pylupdate)) 832 if proc is not None:
833 self.__readStderr(proc, '{0}: '.format(self.pylupdate))
830 else: 834 else:
831 return 835 return
832 836
833 def __readStderrLrelease(self): 837 def __readStderrLrelease(self):
834 """ 838 """
835 Private slot to handle the readyReadStandardError signal of the 839 Private slot to handle the readyReadStandardError signal of the
836 lrelease process. 840 lrelease process.
837 """ 841 """
838 if self.lreleaseProc is not None: 842 proc = self.sender()
839 self.__readStderr(self.lreleaseProc, 'lrelease: ') 843 if proc is not None:
844 self.__readStderr(proc, 'lrelease: ')
840 else: 845 else:
841 return 846 return
842 847
843 def __readStderr(self, proc, ps): 848 def __readStderr(self, proc, ps):
844 """ 849 """
872 Private slot to handle the finished signal of the pylupdate process. 877 Private slot to handle the finished signal of the pylupdate process.
873 878
874 @param exitCode exit code of the process (integer) 879 @param exitCode exit code of the process (integer)
875 @param exitStatus exit status of the process (QProcess.ExitStatus) 880 @param exitStatus exit status of the process (QProcess.ExitStatus)
876 """ 881 """
877 self.pylupdateProcRunning = False
878 if exitStatus == QProcess.NormalExit and exitCode == 0: 882 if exitStatus == QProcess.NormalExit and exitCode == 0:
879 ui = e5App().getObject("UserInterface") 883 ui = e5App().getObject("UserInterface")
880 if ui.notificationsEnabled(): 884 if ui.notificationsEnabled():
881 ui.showNotification(UI.PixmapCache.getPixmap("linguist48.png"), 885 ui.showNotification(UI.PixmapCache.getPixmap("linguist48.png"),
882 self.trUtf8("Translation file generation"), 886 self.trUtf8("Translation file generation"),
889 " was successful.")) 893 " was successful."))
890 else: 894 else:
891 E5MessageBox.critical(self, 895 E5MessageBox.critical(self,
892 self.trUtf8("Translation file generation"), 896 self.trUtf8("Translation file generation"),
893 self.trUtf8("The generation of the translation files (*.ts) has failed.")) 897 self.trUtf8("The generation of the translation files (*.ts) has failed."))
894 self.pylupdateProc = None 898
899 proc = self.sender()
900 for index in range(len(self.__pylupdateProcesses)):
901 if proc == self.__pylupdateProcesses[index][0]:
902 try:
903 self.__tmpProjects.remove(self.__pylupdateProcesses[index][1])
904 os.remove(self.__pylupdateProcesses[index][1])
905 except EnvironmentError:
906 pass
907 del self.__pylupdateProcesses[index]
908 break
909 if not self.__pylupdateProcesses:
910 # all done
911 self.pylupdateProcRunning = False
895 912
896 def __generateTSFile(self, noobsolete=False, generateAll=True): 913 def __generateTSFile(self, noobsolete=False, generateAll=True):
897 """ 914 """
898 Private method used to run pylupdate/pylupdate4 to generate the .ts files. 915 Private method used to run pylupdate/pylupdate4 to generate the .ts files.
899 916
931 for lang in langs] 948 for lang in langs]
932 self.hooks["generateSelectedWithObsolete"](l) 949 self.hooks["generateSelectedWithObsolete"](l)
933 return 950 return
934 951
935 # generate a minimal temporary projectfile suitable for pylupdate 952 # generate a minimal temporary projectfile suitable for pylupdate
953 self.__tmpProjects = []
936 if self.project.pdata["PROGLANGUAGE"][0] in ["Python", "Python2", "Python3"]: 954 if self.project.pdata["PROGLANGUAGE"][0] in ["Python", "Python2", "Python3"]:
937 ok = self.__writeTempProjectFile(langs, [".py"]) 955 ok = self.__writeTempProjectFile(langs, [".py"])
938 else: 956 else:
939 ok = False 957 ok = False
940 if not ok: 958 if not ok:
951 elif self.project.getProjectType() in ["PySide", "PySideC"]: 969 elif self.project.getProjectType() in ["PySide", "PySideC"]:
952 self.pylupdate = Utilities.generatePySideToolPath('pyside-lupdate') 970 self.pylupdate = Utilities.generatePySideToolPath('pyside-lupdate')
953 else: 971 else:
954 return 972 return
955 973
956 for tempProjectFile in self.tmpProject: 974 self.__pylupdateProcesses = []
957 self.pylupdateProc = QProcess() 975 for tempProjectFile in self.__tmpProjects[:]:
976 proc = QProcess()
958 args = [] 977 args = []
959 978
960 if noobsolete: 979 if noobsolete:
961 args.append('-noobsolete') 980 args.append('-noobsolete')
962 981
963 args.append('-verbose') 982 args.append('-verbose')
964 path, filename = os.path.split(tempProjectFile) 983 path, filename = os.path.split(tempProjectFile)
965 args.append(filename) 984 args.append(filename)
966 self.pylupdateProc.setWorkingDirectory(os.path.join(self.project.ppath, path)) 985 proc.setWorkingDirectory(os.path.join(self.project.ppath, path))
967 self.pylupdateProc.finished.connect(self.__generateTSFileDone) 986 proc.finished.connect(self.__generateTSFileDone)
968 self.pylupdateProc.readyReadStandardOutput.connect(self.__readStdoutLupdate) 987 proc.readyReadStandardOutput.connect(self.__readStdoutLupdate)
969 self.pylupdateProc.readyReadStandardError.connect(self.__readStderrLupdate) 988 proc.readyReadStandardError.connect(self.__readStderrLupdate)
970 989
971 self.pylupdateProc.start(self.pylupdate, args) 990 proc.start(self.pylupdate, args)
972 procStarted = self.pylupdateProc.waitForStarted(5000) 991 procStarted = proc.waitForStarted()
973 if procStarted: 992 if procStarted:
974 self.pylupdateProcRunning = True 993 self.pylupdateProcRunning = True
975 self.pylupdateProc.waitForFinished(10000) 994 self.__pylupdateProcesses.append((proc, tempProjectFile))
976 else: 995 else:
977 E5MessageBox.critical(self, 996 E5MessageBox.critical(self,
978 self.trUtf8('Process Generation Error'), 997 self.trUtf8('Process Generation Error'),
979 self.trUtf8( 998 self.trUtf8(
980 'Could not start {0}.<br>' 999 'Could not start {0}.<br>'
981 'Ensure that it is in the search path.' 1000 'Ensure that it is in the search path.'
982 ).format(self.pylupdate)) 1001 ).format(self.pylupdate))
983 # cleanup 1002 # cleanup
984 try: 1003 try:
985 for fn in self.tmpProject: 1004 self.__tmpProjects.remove(tempProjectFile)
986 os.remove(fn) 1005 os.remove(tempProjectFile)
987 except EnvironmentError: 1006 except EnvironmentError:
988 pass 1007 pass
989 self.tmpProject = []
990 1008
991 def __generateAll(self): 1009 def __generateAll(self):
992 """ 1010 """
993 Private method to generate all translation files (.ts) for Qt Linguist. 1011 Private method to generate all translation files (.ts) for Qt Linguist.
994 1012
1052 shutil.move(qmFile, target) 1070 shutil.move(qmFile, target)
1053 else: 1071 else:
1054 E5MessageBox.critical(self, 1072 E5MessageBox.critical(self,
1055 self.trUtf8("Translation file release"), 1073 self.trUtf8("Translation file release"),
1056 self.trUtf8("The release of the translation files (*.qm) has failed.")) 1074 self.trUtf8("The release of the translation files (*.qm) has failed."))
1057 self.lreleaseProc = None 1075
1058 try: 1076 proc = self.sender()
1059 os.remove(self.tmpProject) 1077 for index in range(len(self.__lreleaseProcesses)):
1060 except EnvironmentError: 1078 if proc == self.__lreleaseProcesses[index][0]:
1061 pass 1079 try:
1062 self.tmpProject = None 1080 self.__tmpProjects.remove(self.__lreleaseProcesses[index][1])
1063 self.project.checkLanguageFiles() 1081 os.remove(self.__lreleaseProcesses[index][1])
1082 except EnvironmentError:
1083 pass
1084 del self.__lreleaseProcesses[index]
1085 break
1086 if not self.__lreleaseProcesses:
1087 # all done
1088 self.lreleaseProcRunning = False
1089 self.project.checkLanguageFiles()
1064 1090
1065 def __releaseTSFile(self, generateAll=False): 1091 def __releaseTSFile(self, generateAll=False):
1066 """ 1092 """
1067 Private method to run lrelease to release the translation files (.qm). 1093 Private method to run lrelease to release the translation files (.qm).
1068 1094
1085 for lang in langs] 1111 for lang in langs]
1086 self.hooks["releaseSelected"](l) 1112 self.hooks["releaseSelected"](l)
1087 return 1113 return
1088 1114
1089 # generate a minimal temporary projectfile suitable for lrelease 1115 # generate a minimal temporary projectfile suitable for lrelease
1116 self.__tmpProjects = []
1090 if self.project.pdata["PROGLANGUAGE"][0] in ["Python", "Python2", "Python3"]: 1117 if self.project.pdata["PROGLANGUAGE"][0] in ["Python", "Python2", "Python3"]:
1091 ok = self.__writeTempProjectFile(langs, [".py"]) 1118 ok = self.__writeTempProjectFile(langs, [".py"])
1092 else: 1119 else:
1093 ok = False 1120 ok = False
1094 if not ok: 1121 if not ok:
1095 return 1122 return
1096
1097 self.lreleaseProc = QProcess()
1098 args = []
1099 1123
1100 if self.project.getProjectType() in \ 1124 if self.project.getProjectType() in \
1101 ["Qt4", "Qt4C", "PyQt5", "PyQt5C", "E4Plugin", "PySide", "PySideC"]: 1125 ["Qt4", "Qt4C", "PyQt5", "PyQt5C", "E4Plugin", "PySide", "PySideC"]:
1102 lrelease = os.path.join( 1126 lrelease = os.path.join(
1103 Utilities.getQtBinariesPath(), 1127 Utilities.getQtBinariesPath(),
1105 else: 1129 else:
1106 return 1130 return
1107 if Utilities.isWindowsPlatform(): 1131 if Utilities.isWindowsPlatform():
1108 lrelease = lrelease + '.exe' 1132 lrelease = lrelease + '.exe'
1109 1133
1110 args.append('-verbose') 1134 self.__lreleaseProcesses = []
1111 args.append(self.tmpProject) 1135 for tempProjectFile in self.__tmpProjects[:]:
1112 self.lreleaseProc.setWorkingDirectory(self.project.ppath) 1136 proc = QProcess()
1113 self.lreleaseProc.finished.connect(self.__releaseTSFileDone) 1137 args = []
1114 self.lreleaseProc.readyReadStandardOutput.connect(self.__readStdoutLrelease) 1138
1115 self.lreleaseProc.readyReadStandardError.connect(self.__readStderrLrelease) 1139 args.append('-verbose')
1116 1140 path, filename = os.path.split(tempProjectFile)
1117 self.lreleaseProc.start(lrelease, args) 1141 args.append(filename)
1118 procStarted = self.lreleaseProc.waitForStarted(5000) 1142 proc.setWorkingDirectory(os.path.join(self.project.ppath, path))
1119 if procStarted: 1143 proc.finished.connect(self.__releaseTSFileDone)
1120 self.lreleaseProcRunning = True 1144 proc.readyReadStandardOutput.connect(self.__readStdoutLrelease)
1121 else: 1145 proc.readyReadStandardError.connect(self.__readStderrLrelease)
1122 E5MessageBox.critical(self, 1146
1123 self.trUtf8('Process Generation Error'), 1147 proc.start(lrelease, args)
1124 self.trUtf8( 1148 procStarted = proc.waitForStarted()
1125 '<p>Could not start lrelease.<br>' 1149 if procStarted:
1126 'Ensure that it is available as <b>{0}</b>.</p>' 1150 self.lreleaseProcRunning = True
1127 ).format(lrelease)) 1151 self.__lreleaseProcesses.append((proc, tempProjectFile))
1152 else:
1153 E5MessageBox.critical(self,
1154 self.trUtf8('Process Generation Error'),
1155 self.trUtf8(
1156 '<p>Could not start lrelease.<br>'
1157 'Ensure that it is available as <b>{0}</b>.</p>'
1158 ).format(lrelease))
1159
1160 # cleanup
1161 try:
1162 self.__tmpProjects.remove(tempProjectFile)
1163 os.remove(tempProjectFile)
1164 except EnvironmentError:
1165 pass
1128 1166
1129 def __releaseSelected(self): 1167 def __releaseSelected(self):
1130 """ 1168 """
1131 Private method to release the translation files (.qm). 1169 Private method to release the translation files (.qm).
1132 """ 1170 """

eric ide

mercurial