diff -r 2570efe87180 -r 06c9e4d45f9f Project/ProjectTranslationsBrowser.py --- a/Project/ProjectTranslationsBrowser.py Wed Jul 10 21:46:22 2013 +0200 +++ b/Project/ProjectTranslationsBrowser.py Thu Jul 11 18:44:57 2013 +0200 @@ -73,8 +73,9 @@ self.lreleaseProc = None self.lreleaseProcRunning = False - self.pylupdateProc = None self.pylupdateProcRunning = False + self.__tmpProjects = [] + self.__pylupdateProcesses = [] def _createPopupMenus(self): """ @@ -699,7 +700,6 @@ break if addIt: sources.append(s) - sections = [("SOURCES", sources)] _forms = [f for f in self.project.pdata["FORMS"] if f.endswith('.ui')] forms = [] @@ -711,63 +711,82 @@ break if addIt: forms.append(f) - sections.append(("FORMS", forms)) if langs: - l = [self.project.getRelativePath(lang.fileName()) \ + langs = [self.project.getRelativePath(lang.fileName()) \ for lang in langs if lang.fileName().endswith('.ts')] else: try: pattern = self.project.pdata["TRANSLATIONPATTERN"][0]\ .replace("%language%", "*") - l = [lang for lang in self.project.pdata["TRANSLATIONS"] \ + langs = [lang for lang in self.project.pdata["TRANSLATIONS"] \ if fnmatch.fnmatch(lang, pattern)] except IndexError: - l = [] - if l: - sections.append(("TRANSLATIONS", l)) - else: + langs = [] + if not langs: E5MessageBox.warning(self, self.trUtf8("Write temporary project file"), self.trUtf8("""No translation files (*.ts) selected.""")) return False - try: - pf = open(pfile, "w", encoding="utf-8") - for key, list in sections: - if len(list) > 0: - pf.write('{0} = '.format(key)) - last = len(list) - 1 - if last > 0: - pf.write('{0} \\{1}'.format( - list[0].replace(os.sep, '/'), "\n")) - for i in range(1, last): - pf.write('\t{0} \\{1}'.format( - list[i].replace(os.sep, '/'), "\n")) - pf.write('\t{0} {1}{2}'.format( - list[last].replace(os.sep, '/'), "\n", "\n")) - else: - pf.write('{0} {1}{2}'.format( - list[0].replace(os.sep, '/'), "\n", "\n")) - - pf.close() - self.tmpProject = pfile - return True - except IOError: - E5MessageBox.critical(self, - self.trUtf8("Write temporary project file"), - self.trUtf8("<p>The temporary project file <b>{0}</b> could not" - " be written.</p>").format(pfile)) - self.tmpProject = None + # create a prefix relative from the *.ts down to the project path + langLevel = {} + for lang in langs: + level = lang.count(os.sep) + lst = langLevel.get(level, []) + lst.append(lang) + langLevel[level] = lst + + for level, langs in langLevel.items(): + prefix = '../' * level + sections = [("SOURCES", + [prefix + src for src in sources])] + sections.append(("FORMS", + [prefix + form for form in forms])) + sections.append(("TRANSLATIONS", + [prefix + lang for lang in langs])) + + dir, name = os.path.split(pfile) + outFile = os.path.join(dir, os.path.dirname(langs[0]), name) + try: + pf = open(outFile, "w", encoding="utf-8") + for key, list in sections: + if len(list) > 0: + pf.write('{0} = '.format(key)) + last = len(list) - 1 + if last > 0: + pf.write('{0} \\{1}'.format( + list[0].replace(os.sep, '/'), "\n")) + for i in range(1, last): + pf.write('\t{0} \\{1}'.format( + list[i].replace(os.sep, '/'), "\n")) + pf.write('\t{0} {1}{2}'.format( + list[last].replace(os.sep, '/'), "\n", "\n")) + else: + pf.write('{0} {1}{2}'.format( + list[0].replace(os.sep, '/'), "\n", "\n")) + + pf.close() + self.__tmpProjects.append(outFile) + except IOError: + E5MessageBox.critical(self, + self.trUtf8("Write temporary project file"), + self.trUtf8("<p>The temporary project file <b>{0}</b> could not" + " be written.</p>").format(outFile)) + + if len(self.__tmpProjects) == 0: return False + return True + def __readStdoutLupdate(self): """ Private slot to handle the readyReadStandardOutput signal of the pylupdate process. """ - if self.pylupdateProc is not None: - self.__readStdout(self.pylupdateProc, '{0}: '.format(self.pylupdate)) + proc = self.sender() + if proc is not None: + self.__readStdout(proc, '{0}: '.format(self.pylupdate)) else: return @@ -802,8 +821,9 @@ Private slot to handle the readyReadStandardError signal of the pylupdate process. """ - if self.pylupdateProc is not None: - self.__readStderr(self.pylupdateProc, '{0}: '.format(self.pylupdate)) + proc = self.sender() + if proc is not None: + self.__readStderr(proc, '{0}: '.format(self.pylupdate)) else: return @@ -851,7 +871,6 @@ @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ - self.pylupdateProcRunning = False if exitStatus == QProcess.NormalExit and exitCode == 0: ui = e5App().getObject("UserInterface") if ui.notificationsEnabled(): @@ -868,13 +887,19 @@ E5MessageBox.critical(self, self.trUtf8("Translation file generation"), self.trUtf8("The generation of the translation files (*.ts) has failed.")) - self.pylupdateProc = None - self.pylupdate = "" - try: - os.remove(self.tmpProject) - except EnvironmentError: - pass - self.tmpProject = None + + proc = self.sender() + for index in range(len(self.__pylupdateProcesses)): + if proc == self.__pylupdateProcesses[index][0]: + try: + os.remove(self.__pylupdateProcesses[index][1]) + except EnvironmentError: + pass + del self.__pylupdateProcesses[index] + break + if not self.__pylupdateProcesses: + # all done + self.pylupdateProcRunning = False def __generateTSFile(self, noobsolete=False, generateAll=True): """ @@ -923,9 +948,6 @@ if not ok: return - self.pylupdateProc = QProcess() - args = [] - if self.project.getProjectType() in ["Qt4", "Qt4C", "E4Plugin"]: self.pylupdate = 'pylupdate4' if Utilities.isWindowsPlatform(): @@ -938,28 +960,42 @@ self.pylupdate = Utilities.generatePySideToolPath('pyside-lupdate') else: return - - if noobsolete: - args.append('-noobsolete') - - args.append('-verbose') - args.append(self.tmpProject) - self.pylupdateProc.setWorkingDirectory(self.project.ppath) - self.pylupdateProc.finished.connect(self.__generateTSFileDone) - self.pylupdateProc.readyReadStandardOutput.connect(self.__readStdoutLupdate) - self.pylupdateProc.readyReadStandardError.connect(self.__readStderrLupdate) - - self.pylupdateProc.start(self.pylupdate, args) - procStarted = self.pylupdateProc.waitForStarted(5000) - if procStarted: - self.pylupdateProcRunning = True - else: - E5MessageBox.critical(self, - self.trUtf8('Process Generation Error'), - self.trUtf8( - 'Could not start {0}.<br>' - 'Ensure that it is in the search path.' - ).format(self.pylupdate)) + + self.__pylupdateProcesses = [] + for tempProjectFile in self.__tmpProjects[:]: + proc = QProcess() + args = [] + + if noobsolete: + args.append('-noobsolete') + + args.append('-verbose') + path, filename = os.path.split(tempProjectFile) + args.append(filename) + proc.setWorkingDirectory(os.path.join(self.project.ppath, path)) + proc.finished.connect(self.__generateTSFileDone) + proc.readyReadStandardOutput.connect(self.__readStdoutLupdate) + proc.readyReadStandardError.connect(self.__readStderrLupdate) + + proc.start(self.pylupdate, args) + procStarted = proc.waitForStarted() + if procStarted: + self.pylupdateProcRunning = True + self.__pylupdateProcesses.append((proc, tempProjectFile)) + else: + E5MessageBox.critical(self, + self.trUtf8('Process Generation Error'), + self.trUtf8( + 'Could not start {0}.<br>' + 'Ensure that it is in the search path.' + ).format(self.pylupdate)) + + # cleanup + try: + self.__tmpProjects.remove(tempProjectFile) + os.remove(tempProjectFile) + except EnvironmentError: + pass def __generateAll(self): """