--- a/src/eric7/Project/ProjectResourcesBrowser.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/Project/ProjectResourcesBrowser.py Wed Jul 13 14:55:47 2022 +0200 @@ -19,8 +19,10 @@ from EricWidgets.EricProgressDialog import EricProgressDialog from .ProjectBrowserModel import ( - ProjectBrowserFileItem, ProjectBrowserSimpleDirectoryItem, - ProjectBrowserDirectoryItem, ProjectBrowserResourceType + ProjectBrowserFileItem, + ProjectBrowserSimpleDirectoryItem, + ProjectBrowserDirectoryItem, + ProjectBrowserResourceType, ) from .ProjectBaseBrowser import ProjectBaseBrowser @@ -34,42 +36,46 @@ class ProjectResourcesBrowser(ProjectBaseBrowser): """ A class used to display the resources part of the project. - + @signal appendStderr(str) emitted after something was received from a QProcess on stderr @signal showMenu(str, QMenu) emitted when a menu is about to be shown. The name of the menu and a reference to the menu are given. """ + appendStderr = pyqtSignal(str) showMenu = pyqtSignal(str, QMenu) - + RCFilenameFormatPython = "{0}_rc.py" RCFilenameFormatRuby = "{0}_rc.rb" - + def __init__(self, project, parent=None): """ Constructor - + @param project reference to the project object @param parent parent widget of this browser (QWidget) """ - ProjectBaseBrowser.__init__(self, project, ProjectBrowserResourceType, - parent) - - self.selectedItemsFilter = [ProjectBrowserFileItem, - ProjectBrowserSimpleDirectoryItem] - - self.setWindowTitle(self.tr('Resources')) + ProjectBaseBrowser.__init__(self, project, ProjectBrowserResourceType, parent) + + self.selectedItemsFilter = [ + ProjectBrowserFileItem, + ProjectBrowserSimpleDirectoryItem, + ] + + self.setWindowTitle(self.tr("Resources")) - self.setWhatsThis(self.tr( - """<b>Project Resources Browser</b>""" - """<p>This allows to easily see all resources contained in the""" - """ current project. Several actions can be executed via the""" - """ context menu.</p>""" - )) - + self.setWhatsThis( + self.tr( + """<b>Project Resources Browser</b>""" + """<p>This allows to easily see all resources contained in the""" + """ current project. Several actions can be executed via the""" + """ context menu.</p>""" + ) + ) + self.compileProc = None - + def _createPopupMenus(self): """ Protected overloaded method to generate the popup menu. @@ -78,270 +84,291 @@ self.multiMenuActions = [] self.dirMenuActions = [] self.dirMultiMenuActions = [] - + self.menu = QMenu(self) if self.project.getProjectType() in [ - "PyQt5", "PyQt5C", - "PySide2", "PySide2C", "PySide6", "PySide6C" + "PyQt5", + "PyQt5C", + "PySide2", + "PySide2C", + "PySide6", + "PySide6C", ]: + self.menu.addAction(self.tr("Compile resource"), self.__compileResource) self.menu.addAction( - self.tr('Compile resource'), - self.__compileResource) - self.menu.addAction( - self.tr('Compile all resources'), - self.__compileAllResources) + self.tr("Compile all resources"), self.__compileAllResources + ) self.menu.addSeparator() self.menu.addAction( - self.tr('Configure rcc Compiler'), - self.__configureRccCompiler) + self.tr("Configure rcc Compiler"), self.__configureRccCompiler + ) self.menu.addSeparator() else: if self.hooks["compileResource"] is not None: self.menu.addAction( self.hooksMenuEntries.get( - "compileResource", - self.tr('Compile resource')), - self.__compileResource) + "compileResource", self.tr("Compile resource") + ), + self.__compileResource, + ) if self.hooks["compileAllResources"] is not None: self.menu.addAction( self.hooksMenuEntries.get( - "compileAllResources", - self.tr('Compile all resources')), - self.__compileAllResources) + "compileAllResources", self.tr("Compile all resources") + ), + self.__compileAllResources, + ) if ( - self.hooks["compileResource"] is not None or - self.hooks["compileAllResources"] is not None + self.hooks["compileResource"] is not None + or self.hooks["compileAllResources"] is not None ): self.menu.addSeparator() - self.menu.addAction(self.tr('Open'), self.__openFile) + self.menu.addAction(self.tr("Open"), self.__openFile) self.menu.addSeparator() - act = self.menu.addAction(self.tr('Rename file'), self._renameFile) + act = self.menu.addAction(self.tr("Rename file"), self._renameFile) self.menuActions.append(act) - act = self.menu.addAction( - self.tr('Remove from project'), self._removeFile) + act = self.menu.addAction(self.tr("Remove from project"), self._removeFile) self.menuActions.append(act) - act = self.menu.addAction(self.tr('Delete'), self.__deleteFile) + act = self.menu.addAction(self.tr("Delete"), self.__deleteFile) self.menuActions.append(act) self.menu.addSeparator() if self.project.getProjectType() in [ - "PyQt5", "PyQt5C", - "PySide2", "PySide2C", "PySide6", "PySide6C" + "PyQt5", + "PyQt5C", + "PySide2", + "PySide2C", + "PySide6", + "PySide6C", ]: - self.menu.addAction( - self.tr('New resource...'), self.__newResource) + self.menu.addAction(self.tr("New resource..."), self.__newResource) else: if self.hooks["newResource"] is not None: self.menu.addAction( self.hooksMenuEntries.get( - "newResource", - self.tr('New resource...')), self.__newResource) - self.menu.addAction( - self.tr('Add resources...'), self.__addResourceFiles) - self.menu.addAction( - self.tr('Add resources directory...'), - self.__addResourcesDirectory) - self.menu.addSeparator() + "newResource", self.tr("New resource...") + ), + self.__newResource, + ) + self.menu.addAction(self.tr("Add resources..."), self.__addResourceFiles) self.menu.addAction( - self.tr('Copy Path to Clipboard'), self._copyToClipboard) + self.tr("Add resources directory..."), self.__addResourcesDirectory + ) + self.menu.addSeparator() + self.menu.addAction(self.tr("Copy Path to Clipboard"), self._copyToClipboard) self.menu.addSeparator() - self.menu.addAction( - self.tr('Expand all directories'), self._expandAllDirs) - self.menu.addAction( - self.tr('Collapse all directories'), self._collapseAllDirs) + self.menu.addAction(self.tr("Expand all directories"), self._expandAllDirs) + self.menu.addAction(self.tr("Collapse all directories"), self._collapseAllDirs) self.menu.addSeparator() - self.menu.addAction(self.tr('Configure...'), self._configure) + self.menu.addAction(self.tr("Configure..."), self._configure) self.backMenu = QMenu(self) if self.project.getProjectType() in [ - "PyQt5", "PyQt5C", - "PySide2", "PySide2C", "PySide6", "PySide6C" + "PyQt5", + "PyQt5C", + "PySide2", + "PySide2C", + "PySide6", + "PySide6C", ]: self.backMenu.addAction( - self.tr('Compile all resources'), - self.__compileAllResources) + self.tr("Compile all resources"), self.__compileAllResources + ) self.backMenu.addSeparator() self.backMenu.addAction( - self.tr('Configure rcc Compiler'), - self.__configureRccCompiler) + self.tr("Configure rcc Compiler"), self.__configureRccCompiler + ) self.backMenu.addSeparator() - self.backMenu.addAction( - self.tr('New resource...'), self.__newResource) + self.backMenu.addAction(self.tr("New resource..."), self.__newResource) else: if self.hooks["compileAllResources"] is not None: self.backMenu.addAction( self.hooksMenuEntries.get( - "compileAllResources", - self.tr('Compile all resources')), - self.__compileAllResources) + "compileAllResources", self.tr("Compile all resources") + ), + self.__compileAllResources, + ) self.backMenu.addSeparator() if self.hooks["newResource"] is not None: self.backMenu.addAction( self.hooksMenuEntries.get( - "newResource", - self.tr('New resource...')), self.__newResource) + "newResource", self.tr("New resource...") + ), + self.__newResource, + ) self.backMenu.addAction( - self.tr('Add resources...'), self.project.addResourceFiles) + self.tr("Add resources..."), self.project.addResourceFiles + ) self.backMenu.addAction( - self.tr('Add resources directory...'), - self.project.addResourceDir) + self.tr("Add resources directory..."), self.project.addResourceDir + ) self.backMenu.addSeparator() + self.backMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs) self.backMenu.addAction( - self.tr('Expand all directories'), self._expandAllDirs) - self.backMenu.addAction( - self.tr('Collapse all directories'), self._collapseAllDirs) + self.tr("Collapse all directories"), self._collapseAllDirs + ) self.backMenu.addSeparator() - self.backMenu.addAction(self.tr('Configure...'), self._configure) + self.backMenu.addAction(self.tr("Configure..."), self._configure) self.backMenu.setEnabled(False) # create the menu for multiple selected files self.multiMenu = QMenu(self) if self.project.getProjectType() in [ - "PyQt5", "PyQt5C", - "PySide2", "PySide2C", "PySide6", "PySide6C" + "PyQt5", + "PyQt5C", + "PySide2", + "PySide2C", + "PySide6", + "PySide6C", ]: act = self.multiMenu.addAction( - self.tr('Compile resources'), - self.__compileSelectedResources) + self.tr("Compile resources"), self.__compileSelectedResources + ) self.multiMenu.addSeparator() self.multiMenu.addAction( - self.tr('Configure rcc Compiler'), - self.__configureRccCompiler) + self.tr("Configure rcc Compiler"), self.__configureRccCompiler + ) self.multiMenu.addSeparator() else: if self.hooks["compileSelectedResources"] is not None: act = self.multiMenu.addAction( self.hooksMenuEntries.get( - "compileSelectedResources", - self.tr('Compile resources')), - self.__compileSelectedResources) + "compileSelectedResources", self.tr("Compile resources") + ), + self.__compileSelectedResources, + ) self.multiMenu.addSeparator() - self.multiMenu.addAction(self.tr('Open'), self.__openFile) + self.multiMenu.addAction(self.tr("Open"), self.__openFile) self.multiMenu.addSeparator() - act = self.multiMenu.addAction( - self.tr('Remove from project'), self._removeFile) + act = self.multiMenu.addAction(self.tr("Remove from project"), self._removeFile) self.multiMenuActions.append(act) - act = self.multiMenu.addAction( - self.tr('Delete'), self.__deleteFile) + act = self.multiMenu.addAction(self.tr("Delete"), self.__deleteFile) self.multiMenuActions.append(act) self.multiMenu.addSeparator() - self.multiMenu.addAction( - self.tr('Expand all directories'), self._expandAllDirs) + self.multiMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs) self.multiMenu.addAction( - self.tr('Collapse all directories'), self._collapseAllDirs) + self.tr("Collapse all directories"), self._collapseAllDirs + ) self.multiMenu.addSeparator() - self.multiMenu.addAction(self.tr('Configure...'), self._configure) + self.multiMenu.addAction(self.tr("Configure..."), self._configure) self.dirMenu = QMenu(self) if self.project.getProjectType() in [ - "PyQt5", "PyQt5C", - "PySide2", "PySide2C", "PySide6", "PySide6C" + "PyQt5", + "PyQt5C", + "PySide2", + "PySide2C", + "PySide6", + "PySide6C", ]: self.dirMenu.addAction( - self.tr('Compile all resources'), - self.__compileAllResources) + self.tr("Compile all resources"), self.__compileAllResources + ) self.dirMenu.addSeparator() self.dirMenu.addAction( - self.tr('Configure rcc Compiler'), - self.__configureRccCompiler) + self.tr("Configure rcc Compiler"), self.__configureRccCompiler + ) self.dirMenu.addSeparator() else: if self.hooks["compileAllResources"] is not None: self.dirMenu.addAction( self.hooksMenuEntries.get( - "compileAllResources", - self.tr('Compile all resources')), - self.__compileAllResources) + "compileAllResources", self.tr("Compile all resources") + ), + self.__compileAllResources, + ) self.dirMenu.addSeparator() - act = self.dirMenu.addAction( - self.tr('Remove from project'), self._removeDir) + act = self.dirMenu.addAction(self.tr("Remove from project"), self._removeDir) self.dirMenuActions.append(act) - act = self.dirMenu.addAction( - self.tr('Delete'), self._deleteDirectory) + act = self.dirMenu.addAction(self.tr("Delete"), self._deleteDirectory) self.dirMenuActions.append(act) self.dirMenu.addSeparator() - self.dirMenu.addAction( - self.tr('New resource...'), self.__newResource) - self.dirMenu.addAction( - self.tr('Add resources...'), self.__addResourceFiles) - self.dirMenu.addAction( - self.tr('Add resources directory...'), - self.__addResourcesDirectory) - self.dirMenu.addSeparator() + self.dirMenu.addAction(self.tr("New resource..."), self.__newResource) + self.dirMenu.addAction(self.tr("Add resources..."), self.__addResourceFiles) self.dirMenu.addAction( - self.tr('Copy Path to Clipboard'), self._copyToClipboard) + self.tr("Add resources directory..."), self.__addResourcesDirectory + ) self.dirMenu.addSeparator() - self.dirMenu.addAction( - self.tr('Expand all directories'), self._expandAllDirs) + self.dirMenu.addAction(self.tr("Copy Path to Clipboard"), self._copyToClipboard) + self.dirMenu.addSeparator() + self.dirMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs) self.dirMenu.addAction( - self.tr('Collapse all directories'), self._collapseAllDirs) + self.tr("Collapse all directories"), self._collapseAllDirs + ) self.dirMenu.addSeparator() - self.dirMenu.addAction(self.tr('Configure...'), self._configure) - + self.dirMenu.addAction(self.tr("Configure..."), self._configure) + self.dirMultiMenu = QMenu(self) if self.project.getProjectType() in [ - "PyQt5", "PyQt5C", - "PySide2", "PySide2C", "PySide6", "PySide6C" + "PyQt5", + "PyQt5C", + "PySide2", + "PySide2C", + "PySide6", + "PySide6C", ]: self.dirMultiMenu.addAction( - self.tr('Compile all resources'), - self.__compileAllResources) + self.tr("Compile all resources"), self.__compileAllResources + ) self.dirMultiMenu.addSeparator() self.dirMultiMenu.addAction( - self.tr('Configure rcc Compiler'), - self.__configureRccCompiler) + self.tr("Configure rcc Compiler"), self.__configureRccCompiler + ) self.dirMultiMenu.addSeparator() else: if self.hooks["compileAllResources"] is not None: self.dirMultiMenu.addAction( self.hooksMenuEntries.get( - "compileAllResources", - self.tr('Compile all resources')), - self.__compileAllResources) + "compileAllResources", self.tr("Compile all resources") + ), + self.__compileAllResources, + ) self.dirMultiMenu.addSeparator() self.dirMultiMenu.addAction( - self.tr('Add resources...'), - self.project.addResourceFiles) + self.tr("Add resources..."), self.project.addResourceFiles + ) self.dirMultiMenu.addAction( - self.tr('Add resources directory...'), - self.project.addResourceDir) + self.tr("Add resources directory..."), self.project.addResourceDir + ) self.dirMultiMenu.addSeparator() self.dirMultiMenu.addAction( - self.tr('Expand all directories'), self._expandAllDirs) + self.tr("Expand all directories"), self._expandAllDirs + ) self.dirMultiMenu.addAction( - self.tr('Collapse all directories'), self._collapseAllDirs) + self.tr("Collapse all directories"), self._collapseAllDirs + ) self.dirMultiMenu.addSeparator() - self.dirMultiMenu.addAction( - self.tr('Configure...'), self._configure) - + self.dirMultiMenu.addAction(self.tr("Configure..."), self._configure) + self.menu.aboutToShow.connect(self.__showContextMenu) self.multiMenu.aboutToShow.connect(self.__showContextMenuMulti) self.dirMenu.aboutToShow.connect(self.__showContextMenuDir) self.dirMultiMenu.aboutToShow.connect(self.__showContextMenuDirMulti) self.backMenu.aboutToShow.connect(self.__showContextMenuBack) self.mainMenu = self.menu - + def _contextMenuRequested(self, coord): """ Protected slot to show the context menu. - + @param coord the position of the mouse pointer (QPoint) """ if not self.project.isOpen(): return - + with contextlib.suppress(Exception): categories = self.getSelectedItemsCountCategorized( - [ProjectBrowserFileItem, ProjectBrowserSimpleDirectoryItem]) + [ProjectBrowserFileItem, ProjectBrowserSimpleDirectoryItem] + ) cnt = categories["sum"] if cnt <= 1: index = self.indexAt(coord) if index.isValid(): self._selectSingleItem(index) categories = self.getSelectedItemsCountCategorized( - [ProjectBrowserFileItem, - ProjectBrowserSimpleDirectoryItem]) + [ProjectBrowserFileItem, ProjectBrowserSimpleDirectoryItem] + ) cnt = categories["sum"] - + bfcnt = categories[str(ProjectBrowserFileItem)] sdcnt = categories[str(ProjectBrowserSimpleDirectoryItem)] if cnt > 1 and cnt == bfcnt: @@ -359,47 +386,47 @@ self.backMenu.popup(self.mapToGlobal(coord)) else: self.backMenu.popup(self.mapToGlobal(coord)) - + def __showContextMenu(self): """ Private slot called by the menu aboutToShow signal. """ ProjectBaseBrowser._showContextMenu(self, self.menu) - + self.showMenu.emit("Main", self.menu) - + def __showContextMenuMulti(self): """ Private slot called by the multiMenu aboutToShow signal. """ ProjectBaseBrowser._showContextMenuMulti(self, self.multiMenu) - + self.showMenu.emit("MainMulti", self.multiMenu) - + def __showContextMenuDir(self): """ Private slot called by the dirMenu aboutToShow signal. """ ProjectBaseBrowser._showContextMenuDir(self, self.dirMenu) - + self.showMenu.emit("MainDir", self.dirMenu) - + def __showContextMenuDirMulti(self): """ Private slot called by the dirMultiMenu aboutToShow signal. """ ProjectBaseBrowser._showContextMenuDirMulti(self, self.dirMultiMenu) - + self.showMenu.emit("MainDirMulti", self.dirMultiMenu) - + def __showContextMenuBack(self): """ Private slot called by the backMenu aboutToShow signal. """ ProjectBaseBrowser._showContextMenuBack(self, self.backMenu) - + self.showMenu.emit("MainBack", self.backMenu) - + def __addResourceFiles(self): """ Private method to add resource files to the project. @@ -408,14 +435,13 @@ if isinstance(itm, ProjectBrowserFileItem): dn = os.path.dirname(itm.fileName()) elif isinstance( - itm, - (ProjectBrowserSimpleDirectoryItem, ProjectBrowserDirectoryItem) + itm, (ProjectBrowserSimpleDirectoryItem, ProjectBrowserDirectoryItem) ): dn = itm.dirName() else: dn = None - self.project.addFiles('resource', dn) - + self.project.addFiles("resource", dn) + def __addResourcesDirectory(self): """ Private method to add resource files of a directory to the project. @@ -424,20 +450,19 @@ if isinstance(itm, ProjectBrowserFileItem): dn = os.path.dirname(itm.fileName()) elif isinstance( - itm, - (ProjectBrowserSimpleDirectoryItem, ProjectBrowserDirectoryItem) + itm, (ProjectBrowserSimpleDirectoryItem, ProjectBrowserDirectoryItem) ): dn = itm.dirName() else: dn = None - self.project.addDirectory('resource', dn) - + self.project.addDirectory("resource", dn) + def _openItem(self): """ Protected slot to handle the open popup menu entry. """ self.__openFile() - + def __openFile(self): """ Private slot to handle the Open menu action. @@ -446,7 +471,7 @@ for itm in itmList[:]: if isinstance(itm, ProjectBrowserFileItem): self.sourceFile.emit(itm.fileName()) - + def __newResource(self): """ Private slot to handle the New Resource menu action. @@ -462,7 +487,7 @@ path = itm.dirName() except AttributeError: path = os.path.join(self.project.ppath, itm.data(0)) - + if self.hooks["newResource"] is not None: self.hooks["newResource"](path) else: @@ -472,12 +497,13 @@ path, self.tr("Qt Resource Files (*.qrc)"), "", - EricFileDialog.DontConfirmOverwrite) - + EricFileDialog.DontConfirmOverwrite, + ) + if not fname: # user aborted or didn't enter a filename return - + fpath = pathlib.Path(fname) if not fpath.suffix: ex = selectedFilter.split("(*")[1].split(")")[0] @@ -488,40 +514,42 @@ self, self.tr("New Resource"), self.tr("The file already exists! Overwrite it?"), - icon=EricMessageBox.Warning) + icon=EricMessageBox.Warning, + ) if not res: # user selected to not overwrite return - + try: - newline = (None if self.project.useSystemEol() - else self.project.getEolString()) - with fpath.open('w', encoding="utf-8", - newline=newline) as rcfile: - rcfile.write('<!DOCTYPE RCC>\n') + newline = ( + None if self.project.useSystemEol() else self.project.getEolString() + ) + with fpath.open("w", encoding="utf-8", newline=newline) as rcfile: + rcfile.write("<!DOCTYPE RCC>\n") rcfile.write('<RCC version="1.0">\n') - rcfile.write('<qresource>\n') - rcfile.write('</qresource>\n') - rcfile.write('</RCC>\n') + rcfile.write("<qresource>\n") + rcfile.write("</qresource>\n") + rcfile.write("</RCC>\n") except OSError as e: EricMessageBox.critical( self, self.tr("New Resource"), self.tr( "<p>The new resource file <b>{0}</b> could not" - " be created.<br>Problem: {1}</p>") - .format(fpath, str(e))) + " be created.<br>Problem: {1}</p>" + ).format(fpath, str(e)), + ) return - + self.project.appendFile(str(fpath)) self.sourceFile.emit(str(fpath)) - + def __deleteFile(self): """ Private method to delete a resource file from the project. """ itmList = self.getSelectedItems() - + files = [] fullNames = [] for itm in itmList: @@ -529,27 +557,27 @@ fullNames.append(fn2) fn = self.project.getRelativePath(fn2) files.append(fn) - - from UI.DeleteFilesConfirmationDialog import ( - DeleteFilesConfirmationDialog - ) + + from UI.DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog + dlg = DeleteFilesConfirmationDialog( self.parent(), self.tr("Delete resources"), self.tr( - "Do you really want to delete these resources from the" - " project?"), - files) - + "Do you really want to delete these resources from the" " project?" + ), + files, + ) + if dlg.exec() == QDialog.DialogCode.Accepted: for fn2, fn in zip(fullNames, files): self.closeSourceWindow.emit(fn2) self.project.deleteFile(fn) - + ########################################################################### ## Methods to handle the various compile commands ########################################################################### - + def __readStdout(self): """ Private slot to handle the readyReadStandardOutput signal of the @@ -558,12 +586,14 @@ if self.compileProc is None: return self.compileProc.setReadChannel(QProcess.ProcessChannel.StandardOutput) - + while self.compileProc and self.compileProc.canReadLine(): - self.buf += str(self.compileProc.readLine(), - Preferences.getSystem("IOEncoding"), - 'replace') - + self.buf += str( + self.compileProc.readLine(), + Preferences.getSystem("IOEncoding"), + "replace", + ) + def __readStderr(self): """ Private slot to handle the readyReadStandardError signal of the @@ -571,36 +601,32 @@ """ if self.compileProc is None: return - + ioEncoding = Preferences.getSystem("IOEncoding") - + self.compileProc.setReadChannel(QProcess.ProcessChannel.StandardError) while self.compileProc and self.compileProc.canReadLine(): - s = self.rccCompiler + ': ' - error = str(self.compileProc.readLine(), - ioEncoding, 'replace') + s = self.rccCompiler + ": " + error = str(self.compileProc.readLine(), ioEncoding, "replace") s += error self.appendStderr.emit(s) - + def __compileQRCDone(self, exitCode, exitStatus): """ Private slot to handle the finished signal of the compile process. - + @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.compileRunning = False ericApp().getObject("ViewManager").enableEditorsCheckFocusIn(True) ui = ericApp().getObject("UserInterface") - if ( - exitStatus == QProcess.ExitStatus.NormalExit and - exitCode == 0 and - self.buf - ): + if exitStatus == QProcess.ExitStatus.NormalExit and exitCode == 0 and self.buf: ofn = os.path.join(self.project.ppath, self.compiledFile) try: - newline = (None if self.project.useSystemEol() - else self.project.getEolString()) + newline = ( + None if self.project.useSystemEol() else self.project.getEolString() + ) with open(ofn, "w", encoding="utf-8", newline=newline) as f: for line in self.buf.splitlines(): f.write(line + "\n") @@ -609,8 +635,8 @@ ui.showNotification( UI.PixmapCache.getPixmap("resourcesCompiler48"), self.tr("Resource Compilation"), - self.tr("The compilation of the resource file" - " was successful.")) + self.tr("The compilation of the resource file" " was successful."), + ) except OSError as msg: if not self.noDialog: EricMessageBox.information( @@ -618,21 +644,23 @@ self.tr("Resource Compilation"), self.tr( "<p>The compilation of the resource file" - " failed.</p><p>Reason: {0}</p>").format(str(msg))) + " failed.</p><p>Reason: {0}</p>" + ).format(str(msg)), + ) else: ui.showNotification( UI.PixmapCache.getPixmap("resourcesCompiler48"), self.tr("Resource Compilation"), - self.tr( - "The compilation of the resource file failed."), + self.tr("The compilation of the resource file failed."), kind=NotificationTypes.CRITICAL, - timeout=0) + timeout=0, + ) self.compileProc = None - + def __compileQRC(self, fn, noDialog=False, progress=None): """ Private method to compile a .qrc file to a .py file. - + @param fn filename of the .ui file to be compiled @param noDialog flag indicating silent operations @param progress reference to the progress dialog @@ -641,35 +669,34 @@ self.compileProc = QProcess() args = [] self.buf = "" - + if self.project.getProjectLanguage() == "Python3": if self.project.getProjectType() in ["PyQt5", "PyQt5C"]: - self.rccCompiler = Utilities.generatePyQtToolPath('pyrcc5') + self.rccCompiler = Utilities.generatePyQtToolPath("pyrcc5") elif self.project.getProjectType() in ["PySide2", "PySide2C"]: self.rccCompiler = Utilities.generatePySideToolPath( - 'pyside2-rcc', variant=2) + "pyside2-rcc", variant=2 + ) elif self.project.getProjectType() in ["PySide6", "PySide6C"]: self.rccCompiler = Utilities.generatePySideToolPath( - 'pyside6-rcc', variant=6) + "pyside6-rcc", variant=6 + ) else: return None defaultParameters = self.project.getDefaultRccCompilerParameters() rccParameters = self.project.pdata["RCCPARAMS"] if ( - rccParameters["CompressionThreshold"] != - defaultParameters["CompressionThreshold"] + rccParameters["CompressionThreshold"] + != defaultParameters["CompressionThreshold"] ): args.append("-threshold") args.append(str(rccParameters["CompressionThreshold"])) - if ( - rccParameters["CompressLevel"] != - defaultParameters["CompressLevel"] - ): + if rccParameters["CompressLevel"] != defaultParameters["CompressLevel"]: args.append("-compress") args.append(str(rccParameters["CompressLevel"])) if ( - rccParameters["CompressionDisable"] != - defaultParameters["CompressionDisable"] + rccParameters["CompressionDisable"] + != defaultParameters["CompressionDisable"] ): args.append("-no-compress") if rccParameters["PathPrefix"] != defaultParameters["PathPrefix"]: @@ -677,25 +704,27 @@ args.append(rccParameters["PathPrefix"]) else: return None - + rcc = self.rccCompiler - + ofn, ext = os.path.splitext(fn) fn = os.path.join(self.project.ppath, fn) - + dirname, filename = os.path.split(ofn) if self.project.getProjectLanguage() == "Python3": self.compiledFile = os.path.join( - dirname, self.RCFilenameFormatPython.format(filename)) + dirname, self.RCFilenameFormatPython.format(filename) + ) elif self.project.getProjectLanguage() == "Ruby": self.compiledFile = os.path.join( - dirname, self.RCFilenameFormatRuby.format(filename)) - + dirname, self.RCFilenameFormatRuby.format(filename) + ) + args.append(fn) self.compileProc.finished.connect(self.__compileQRCDone) self.compileProc.readyReadStandardOutput.connect(self.__readStdout) self.compileProc.readyReadStandardError.connect(self.__readStderr) - + self.noDialog = noDialog self.compileProc.start(rcc, args) procStarted = self.compileProc.waitForStarted(5000) @@ -709,13 +738,13 @@ progress.cancel() EricMessageBox.critical( self, - self.tr('Process Generation Error'), + self.tr("Process Generation Error"), self.tr( - 'Could not start {0}.<br>' - 'Ensure that it is in the search path.' - ).format(self.rccCompiler)) + "Could not start {0}.<br>" "Ensure that it is in the search path." + ).format(self.rccCompiler), + ) return None - + def __compileResource(self): """ Private method to compile a resource to a source file. @@ -727,7 +756,7 @@ self.hooks["compileResource"](fn) else: self.__compileQRC(fn) - + def __compileAllResources(self): """ Private method to compile all resources to source files. @@ -738,12 +767,16 @@ numResources = len(self.project.pdata["RESOURCES"]) progress = EricProgressDialog( self.tr("Compiling resources..."), - self.tr("Abort"), 0, numResources, - self.tr("%v/%m Resources"), self) + self.tr("Abort"), + 0, + numResources, + self.tr("%v/%m Resources"), + self, + ) progress.setModal(True) progress.setMinimumDuration(0) progress.setWindowTitle(self.tr("Resources")) - + for prog, fn in enumerate(self.project.pdata["RESOURCES"]): progress.setValue(prog) if progress.wasCanceled(): @@ -756,32 +789,35 @@ else: break progress.setValue(numResources) - + def __compileSelectedResources(self): """ Private method to compile selected resources to source files. """ items = self.getSelectedItems() - files = [self.project.getRelativePath(itm.fileName()) - for itm in items] - + files = [self.project.getRelativePath(itm.fileName()) for itm in items] + if self.hooks["compileSelectedResources"] is not None: self.hooks["compileSelectedResources"](files) else: numResources = len(files) progress = EricProgressDialog( self.tr("Compiling resources..."), - self.tr("Abort"), 0, numResources, - self.tr("%v/%m Resources"), self) + self.tr("Abort"), + 0, + numResources, + self.tr("%v/%m Resources"), + self, + ) progress.setModal(True) progress.setMinimumDuration(0) progress.setWindowTitle(self.tr("Resources")) - + for prog, fn in enumerate(files): progress.setValue(prog) if progress.wasCanceled(): break - if not fn.endswith('.ui.h'): + if not fn.endswith(".ui.h"): proc = self.__compileQRC(fn, True, progress) if proc is not None: while proc.state() == QProcess.ProcessState.Running: @@ -790,12 +826,12 @@ else: break progress.setValue(numResources) - + def __checkResourcesNewer(self, filename, mtime): """ Private method to check, if any file referenced in a resource file is newer than a given time. - + @param filename filename of the resource file (string) @param mtime modification time to check against @return flag indicating some file is newer (boolean) @@ -805,15 +841,12 @@ buf = f.read() except OSError: return False - + qrcDirName = os.path.dirname(filename) lbuf = "" for line in buf.splitlines(): line = line.strip() - if ( - line.lower().startswith("<file>") or - line.lower().startswith("<file ") - ): + if line.lower().startswith("<file>") or line.lower().startswith("<file "): lbuf = line elif lbuf: lbuf = "{0}{1}".format(lbuf, line) @@ -821,34 +854,35 @@ rfile = lbuf.split(">", 1)[1].split("<", 1)[0] if not os.path.isabs(rfile): rfile = os.path.join(qrcDirName, rfile) - if ( - os.path.exists(rfile) and - os.stat(rfile).st_mtime > mtime - ): + if os.path.exists(rfile) and os.stat(rfile).st_mtime > mtime: return True - + lbuf = "" - + return False - + def compileChangedResources(self): """ Public method to compile all changed resources to source files. """ if self.hooks["compileChangedResources"] is not None: - self.hooks["compileChangedResources"]( - self.project.pdata["RESOURCES"]) + self.hooks["compileChangedResources"](self.project.pdata["RESOURCES"]) else: if len(self.project.pdata["RESOURCES"]) == 0: # The project does not contain resource files return - + progress = EricProgressDialog( self.tr("Determining changed resources..."), - self.tr("Abort"), 0, 100, self.tr("%v/%m Resources"), self) + self.tr("Abort"), + 0, + 100, + self.tr("%v/%m Resources"), + self, + ) progress.setMinimumDuration(0) progress.setWindowTitle(self.tr("Resources")) - + # get list of changed resources changedResources = [] progress.setMaximum(len(self.project.pdata["RESOURCES"])) @@ -859,25 +893,26 @@ if self.project.getProjectLanguage() == "Python3": dirname, filename = os.path.split(os.path.splitext(ifn)[0]) ofn = os.path.join( - dirname, self.RCFilenameFormatPython.format(filename)) + dirname, self.RCFilenameFormatPython.format(filename) + ) elif self.project.getProjectLanguage() == "Ruby": dirname, filename = os.path.split(os.path.splitext(ifn)[0]) ofn = os.path.join( - dirname, self.RCFilenameFormatRuby.format(filename)) + dirname, self.RCFilenameFormatRuby.format(filename) + ) else: return if ( - not os.path.exists(ofn) or - os.stat(ifn).st_mtime > os.stat(ofn).st_mtime or - self.__checkResourcesNewer(ifn, os.stat(ofn).st_mtime) + not os.path.exists(ofn) + or os.stat(ifn).st_mtime > os.stat(ofn).st_mtime + or self.__checkResourcesNewer(ifn, os.stat(ofn).st_mtime) ): changedResources.append(fn) progress.setValue(len(self.project.pdata["RESOURCES"])) QApplication.processEvents() - + if changedResources: - progress.setLabelText( - self.tr("Compiling changed resources...")) + progress.setLabelText(self.tr("Compiling changed resources...")) progress.setMaximum(len(changedResources)) progress.setValue(0) QApplication.processEvents() @@ -894,21 +929,21 @@ break progress.setValue(len(changedResources)) QApplication.processEvents() - + def handlePreferencesChanged(self): """ Public slot used to handle the preferencesChanged signal. """ ProjectBaseBrowser.handlePreferencesChanged(self) - + def __configureRccCompiler(self): """ Private slot to configure some non-common rcc compiler options. """ from .RccCompilerOptionsDialog import RccCompilerOptionsDialog - + params = self.project.pdata["RCCPARAMS"] - + dlg = RccCompilerOptionsDialog(params) if dlg.exec() == QDialog.DialogCode.Accepted: threshold, compression, noCompression, root = dlg.getData() @@ -924,15 +959,15 @@ if root != params["PathPrefix"]: params["PathPrefix"] = root self.project.setDirty(True) - + ########################################################################### ## Support for hooks below ########################################################################### - + def _initHookMethods(self): """ Protected method to initialize the hooks dictionary. - + Supported hook methods are: <ul> <li>compileResource: takes filename as parameter</li> @@ -943,7 +978,7 @@ <li>newResource: takes full directory path of new file as parameter</li> </ul> - + <b>Note</b>: Filenames are relative to the project directory, if not specified differently. """