--- a/CxFreeze/CxfreezeConfigDialog.py Thu Dec 30 11:53:44 2021 +0100 +++ b/CxFreeze/CxfreezeConfigDialog.py Wed Sep 21 16:47:33 2022 +0200 @@ -28,10 +28,11 @@ """ Class implementing a dialog to enter the parameters for cxfreeze. """ + def __init__(self, project, exe, parms=None, parent=None): """ Constructor - + @param project reference to the project object @type Project @param exe name of the cxfreeze executable @@ -43,231 +44,208 @@ """ QDialog.__init__(self, parent) self.setupUi(self) - - self.selectFileOrFolderButton.setIcon( - UI.PixmapCache.getIcon("open.png")) - - self.targetDirPicker.setMode( - EricPathPickerModes.DIRECTORY_MODE) - self.targetDirPicker.setWindowTitle( - self.tr("Select target directory")) - + + self.selectFileOrFolderButton.setIcon(UI.PixmapCache.getIcon("open.png")) + + self.targetDirPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) + self.targetDirPicker.setWindowTitle(self.tr("Select target directory")) + iconsI18N = self.tr("Icons") allFilesI18N = self.tr("All files") if Utilities.isWindowsPlatform(): - iconFilter = "{0} (*.ico);;{1} (*.*)".format( - iconsI18N, allFilesI18N) + iconFilter = "{0} (*.ico);;{1} (*.*)".format(iconsI18N, allFilesI18N) elif Utilities.isMacPlatform(): - iconFilter = "{0} (*.icns *.png);;{1} (*.*)".format( - iconsI18N, allFilesI18N) + iconFilter = "{0} (*.icns *.png);;{1} (*.*)".format(iconsI18N, allFilesI18N) else: - iconFilter = "{0} (*.png);;{1} (*.*)".format( - iconsI18N, allFilesI18N) - self.applicationIconPicker.setMode( - EricPathPickerModes.OPEN_FILE_MODE) + iconFilter = "{0} (*.png);;{1} (*.*)".format(iconsI18N, allFilesI18N) + self.applicationIconPicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) self.applicationIconPicker.setWindowTitle( - self.tr("Select the application icon")) + self.tr("Select the application icon") + ) self.applicationIconPicker.setFilters(iconFilter) - - self.extListFilePicker.setMode( - EricPathPickerModes.OPEN_FILE_MODE) - self.extListFilePicker.setWindowTitle( - self.tr("Select external list file")) - + + self.extListFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) + self.extListFilePicker.setWindowTitle(self.tr("Select external list file")) + self.__project = project self.__initializeDefaults() - + # get a copy of the defaults to store the user settings self.__parameters = copy.deepcopy(self.defaults) - + # combine it with the values of parms if parms is not None: self.__parameters.update(parms) - + self.cxfreezeExecCombo.addItems(exe) # try to set the saved script path with contextlib.suppress(ValueError): - idx = exe.index(self.__parameters['script']) + idx = exe.index(self.__parameters["script"]) self.cxfreezeExecCombo.setCurrentIndex(idx) - + # initialize general tab - self.targetDirPicker.setText( - self.__parameters['targetDirectory']) - self.targetNameEdit.setText( - self.__parameters['targetName']) - self.basenameCombo.setEditText( - self.__parameters['baseName']) - self.initscriptCombo.setEditText( - self.__parameters['initScript']) - self.applicationIconPicker.setText( - self.__parameters['applicationIcon']) - self.keeppathCheckBox.setChecked( - self.__parameters['keepPath']) - self.compressCheckBox.setChecked( - self.__parameters['compress']) - if self.__parameters['optimize'] == 0: + self.targetDirPicker.setText(self.__parameters["targetDirectory"]) + self.targetNameEdit.setText(self.__parameters["targetName"]) + self.basenameCombo.setEditText(self.__parameters["baseName"]) + self.initscriptCombo.setEditText(self.__parameters["initScript"]) + self.applicationIconPicker.setText(self.__parameters["applicationIcon"]) + self.keeppathCheckBox.setChecked(self.__parameters["keepPath"]) + self.compressCheckBox.setChecked(self.__parameters["compress"]) + if self.__parameters["optimize"] == 0: self.nooptimizeRadioButton.setChecked(True) - elif self.__parameters['optimize'] == 1: + elif self.__parameters["optimize"] == 1: self.optimizeRadioButton.setChecked(True) else: self.optimizeDocRadioButton.setChecked(True) - + # initialize advanced tab - self.defaultPathEdit.setText( - os.pathsep.join(self.__parameters['defaultPath'])) - self.includePathEdit.setText( - os.pathsep.join(self.__parameters['includePath'])) + self.defaultPathEdit.setText(os.pathsep.join(self.__parameters["defaultPath"])) + self.includePathEdit.setText(os.pathsep.join(self.__parameters["includePath"])) self.replacePathsEdit.setText( - os.pathsep.join(self.__parameters['replacePaths'])) - self.includeModulesEdit.setText( - ','.join(self.__parameters['includeModules'])) - self.excludeModulesEdit.setText( - ','.join(self.__parameters['excludeModules'])) - self.extListFilePicker.setText(self.__parameters['extListFile']) - + os.pathsep.join(self.__parameters["replacePaths"]) + ) + self.includeModulesEdit.setText(",".join(self.__parameters["includeModules"])) + self.excludeModulesEdit.setText(",".join(self.__parameters["excludeModules"])) + self.extListFilePicker.setText(self.__parameters["extListFile"]) + # initialize additional files tab - self.fileOrFolderList.addItems(self.__parameters['additionalFiles']) - + self.fileOrFolderList.addItems(self.__parameters["additionalFiles"]) + def __initializeDefaults(self): """ Private method to set the default values. - + These are needed later on to generate the command line parameters. """ self.defaults = { # general options - 'targetDirectory': '', - 'targetName': '', - 'baseName': 'Console', - 'initScript': 'Console', - 'applicationIcon': '', - 'script': '', - 'keepPath': False, - 'compress': False, - 'optimize': 0, # 0, 1 or 2 - + "targetDirectory": "", + "targetName": "", + "baseName": "Console", + "initScript": "Console", + "applicationIcon": "", + "script": "", + "keepPath": False, + "compress": False, + "optimize": 0, # 0, 1 or 2 # advanced options - 'defaultPath': [], - 'includePath': [], - 'replacePaths': [], - 'includeModules': [], - 'excludeModules': [], - 'extListFile': '', - + "defaultPath": [], + "includePath": [], + "replacePaths": [], + "includeModules": [], + "excludeModules": [], + "extListFile": "", # additional files tab - 'additionalFiles': [], + "additionalFiles": [], } # overwrite 'baseName' if OS is Windows - if sys.platform == 'win32': - self.defaults['baseName'] = 'Win32GUI' + if sys.platform == "win32": + self.defaults["baseName"] = "Win32GUI" # overwrite 'initScript' if version 3 interpreter - if self.__project.getProjectLanguage() == 'Python3': - self.defaults['initScript'] = 'Console3' - + if self.__project.getProjectLanguage() == "Python3": + self.defaults["initScript"] = "Console3" + def generateParameters(self): """ Public method that generates the command line parameters. - + It generates a list of strings to be used to set the QProcess arguments for the cxfreeze call and a list containing the non default parameters. The second list can be passed back upon object generation to overwrite the default settings. - + @return a tuple of the command line parameters and non default parameters @rtype tuple of (list of str, dict) """ parms = {} args = [] - + # 1. the program name args.append(self.cxfreezeExecCombo.currentText()) - + # 2. the commandline options # 2.1 general options - if ( - self.__parameters['targetDirectory'] != - self.defaults['targetDirectory'] - ): - parms['targetDirectory'] = self.__parameters['targetDirectory'] - args.append('--target-dir={0}'.format( - self.__parameters['targetDirectory'])) - if self.__parameters['targetName'] != self.defaults['targetName']: - parms['targetName'] = self.__parameters['targetName'][:] - args.append('--target-name={0}'.format( - self.__parameters['targetName'])) - parms['baseName'] = self.__parameters['baseName'][:] - if self.__parameters['baseName'] != '': + if self.__parameters["targetDirectory"] != self.defaults["targetDirectory"]: + parms["targetDirectory"] = self.__parameters["targetDirectory"] + args.append("--target-dir={0}".format(self.__parameters["targetDirectory"])) + if self.__parameters["targetName"] != self.defaults["targetName"]: + parms["targetName"] = self.__parameters["targetName"][:] + args.append("--target-name={0}".format(self.__parameters["targetName"])) + parms["baseName"] = self.__parameters["baseName"][:] + if self.__parameters["baseName"] != "": + args.append("--base-name={0}".format(self.__parameters["baseName"])) + parms["initScript"] = self.__parameters["initScript"][:] + if self.__parameters["initScript"] != "": + args.append("--init-script={0}".format(self.__parameters["initScript"])) + parms["applicationIcon"] = self.__parameters["applicationIcon"][:] + if self.__parameters["applicationIcon"] != self.defaults["applicationIcon"]: + args.append("--icon={0}".format(self.__parameters["applicationIcon"])) + parms["script"] = self.__parameters["script"][:] + if self.__parameters["keepPath"] != self.defaults["keepPath"]: + parms["keepPath"] = self.__parameters["keepPath"] + args.append("--no-copy-deps") + if self.__parameters["compress"] != self.defaults["compress"]: + parms["compress"] = self.__parameters["compress"] + args.append("--compress") + if self.__parameters["optimize"] != self.defaults["optimize"]: + parms["optimize"] = self.__parameters["optimize"] + if self.__parameters["optimize"] == 1: + args.append("-O") + elif self.__parameters["optimize"] == 2: + args.append("-OO") + + # 2.2 advanced options + if self.__parameters["defaultPath"] != self.defaults["defaultPath"]: + parms["defaultPath"] = self.__parameters["defaultPath"][:] args.append( - '--base-name={0}'.format(self.__parameters['baseName'])) - parms['initScript'] = self.__parameters['initScript'][:] - if self.__parameters['initScript'] != '': - args.append('--init-script={0}'.format( - self.__parameters['initScript'])) - parms['applicationIcon'] = self.__parameters['applicationIcon'][:] - if ( - self.__parameters['applicationIcon'] != - self.defaults['applicationIcon'] - ): - args.append('--icon={0}'.format( - self.__parameters['applicationIcon'])) - parms['script'] = self.__parameters['script'][:] - if self.__parameters['keepPath'] != self.defaults['keepPath']: - parms['keepPath'] = self.__parameters['keepPath'] - args.append('--no-copy-deps') - if self.__parameters['compress'] != self.defaults['compress']: - parms['compress'] = self.__parameters['compress'] - args.append('--compress') - if self.__parameters['optimize'] != self.defaults['optimize']: - parms['optimize'] = self.__parameters['optimize'] - if self.__parameters['optimize'] == 1: - args.append('-O') - elif self.__parameters['optimize'] == 2: - args.append('-OO') - - # 2.2 advanced options - if self.__parameters['defaultPath'] != self.defaults['defaultPath']: - parms['defaultPath'] = self.__parameters['defaultPath'][:] - args.append('--default-path={0}'.format( - os.pathsep.join(self.__parameters['defaultPath']))) - if self.__parameters['includePath'] != self.defaults['includePath']: - parms['includePath'] = self.__parameters['includePath'][:] - args.append('--include-path={0}'.format( - os.pathsep.join(self.__parameters['includePath']))) - if self.__parameters['replacePaths'] != self.defaults['replacePaths']: - parms['replacePaths'] = self.__parameters['replacePaths'][:] - args.append('--replace-paths={0}'.format( - os.pathsep.join(self.__parameters['replacePaths']))) - if ( - self.__parameters['includeModules'] != - self.defaults['includeModules'] - ): - parms['includeModules'] = self.__parameters['includeModules'][:] - args.append('--include-modules={0}'.format( - ','.join(self.__parameters['includeModules']))) - if ( - self.__parameters['excludeModules'] != - self.defaults['excludeModules'] - ): - parms['excludeModules'] = self.__parameters['excludeModules'][:] - args.append('--exclude-modules={0}'.format( - ','.join(self.__parameters['excludeModules']))) - if self.__parameters['extListFile'] != self.defaults['extListFile']: - parms['extListFile'] = self.__parameters['extListFile'] - args.append('--ext-list-file={0}'.format( - self.__parameters['extListFile'])) - + "--default-path={0}".format( + os.pathsep.join(self.__parameters["defaultPath"]) + ) + ) + if self.__parameters["includePath"] != self.defaults["includePath"]: + parms["includePath"] = self.__parameters["includePath"][:] + args.append( + "--include-path={0}".format( + os.pathsep.join(self.__parameters["includePath"]) + ) + ) + if self.__parameters["replacePaths"] != self.defaults["replacePaths"]: + parms["replacePaths"] = self.__parameters["replacePaths"][:] + args.append( + "--replace-paths={0}".format( + os.pathsep.join(self.__parameters["replacePaths"]) + ) + ) + if self.__parameters["includeModules"] != self.defaults["includeModules"]: + parms["includeModules"] = self.__parameters["includeModules"][:] + args.append( + "--include-modules={0}".format( + ",".join(self.__parameters["includeModules"]) + ) + ) + if self.__parameters["excludeModules"] != self.defaults["excludeModules"]: + parms["excludeModules"] = self.__parameters["excludeModules"][:] + args.append( + "--exclude-modules={0}".format( + ",".join(self.__parameters["excludeModules"]) + ) + ) + if self.__parameters["extListFile"] != self.defaults["extListFile"]: + parms["extListFile"] = self.__parameters["extListFile"] + args.append("--ext-list-file={0}".format(self.__parameters["extListFile"])) + # 2.3 additional files tab - if self.__parameters['additionalFiles'] != []: - parms['additionalFiles'] = self.__parameters['additionalFiles'][:] - + if self.__parameters["additionalFiles"] != []: + parms["additionalFiles"] = self.__parameters["additionalFiles"][:] + return (args, parms) @pyqtSlot(str) def on_cxfreezeExecCombo_currentIndexChanged(self, text): """ Private slot to handle the selection of a cxfreeze executable. - + @param text selected cxfreeze executable @type str """ @@ -276,44 +254,44 @@ # remove "\Scripts\cx_Freeze.bat" from path dirname = os.path.dirname(text) dirname = os.path.dirname(dirname) - + # first try the fast way - modpath = os.path.join( - dirname, "Lib", "site-packages", "cx_Freeze") + modpath = os.path.join(dirname, "Lib", "site-packages", "cx_Freeze") if not os.path.exists(modpath): # but if it failed search in the whole directory tree modpath = None for dirpath, dirnames, _ in os.walk(dirname): - if 'cx_Freeze' in dirnames: + if "cx_Freeze" in dirnames: modpath = os.path.join(dirpath, "cx_Freeze") break else: - with open(text, 'r') as f: + with open(text, "r") as f: args = f.readline() if not args: return - - args = args.strip('!#\n').split(' ') + + args = args.strip("!#\n").split(" ") program = args.pop(0) - script = os.path.join(os.path.dirname(os.path.abspath(__file__)), - 'CxfreezeFindPath.py') + script = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "CxfreezeFindPath.py" + ) if not os.path.exists(script): return - + args.append(script) process = QProcess() process.start(program, args) process.waitForFinished(5000) # get a QByteArray of the output cxPath = process.readAllStandardOutput() - modpath = str(cxPath, encoding='utf-8').strip('\n\r') - if not modpath.endswith('cx_Freeze'): + modpath = str(cxPath, encoding="utf-8").strip("\n\r") + if not modpath.endswith("cx_Freeze"): return - + # populate combo boxes if modpath: - d = QDir(os.path.join(modpath, 'bases')) + d = QDir(os.path.join(modpath, "bases")) basesList = d.entryList(QDir.Filter.Files) if Utilities.isWindowsPlatform(): # strip the final '.exe' from the bases @@ -325,41 +303,40 @@ basesList.append(base) else: basesList.append(b) - - basesList.insert(0, '') + + basesList.insert(0, "") currentText = self.basenameCombo.currentText() self.basenameCombo.clear() self.basenameCombo.addItems(basesList) self.basenameCombo.setEditText(currentText) - - d = QDir(os.path.join(modpath, 'initscripts')) - initList = d.entryList(['*.py']) - initList.insert(0, '') + + d = QDir(os.path.join(modpath, "initscripts")) + initList = d.entryList(["*.py"]) + initList.insert(0, "") currentText = self.initscriptCombo.currentText() self.initscriptCombo.clear() - self.initscriptCombo.addItems( - [os.path.splitext(i)[0] for i in initList]) + self.initscriptCombo.addItems([os.path.splitext(i)[0] for i in initList]) self.initscriptCombo.setEditText(currentText) - + @pyqtSlot(int) def on_fileOrFolderList_currentRowChanged(self, row): """ Private slot to handle the currentRowChanged signal of the fileOrFolderList. - + @param row the current row @type int """ self.deleteSelectedButton.setEnabled(row != -1) if row != -1: self.fileOrFolderList.setCurrentRow(row) - + @pyqtSlot(QListWidgetItem) def on_fileOrFolderList_itemDoubleClicked(self, itm): """ Private slot to handle the itemDoubleClicked signal of the fileOrFolderList. - + @param itm the selected row @type QListWidgetItem """ @@ -367,7 +344,7 @@ row = self.fileOrFolderList.currentRow() itm = self.fileOrFolderList.takeItem(row) del itm - + @pyqtSlot() def on_addFileOrFolderButton_clicked(self): """ @@ -379,17 +356,17 @@ self.fileOrFolderEdit.clear() row = self.fileOrFolderList.currentRow() self.on_fileOrFolderList_currentRowChanged(row) - + @pyqtSlot(str) def on_fileOrFolderEdit_textChanged(self, txt): """ Private slot to handle the textChanged signal of the directory edit. - + @param txt the text of the directory edit @type str """ self.addFileOrFolderButton.setEnabled(txt != "") - + @pyqtSlot() def on_deleteSelectedButton_clicked(self): """ @@ -400,69 +377,78 @@ del itm row = self.fileOrFolderList.currentRow() self.on_fileOrFolderList_currentRowChanged(row) - + @pyqtSlot() def on_selectFileOrFolderButton_clicked(self): """ Private slot to select files or folders. - + It displays a file and directory selection dialog to select the files and directories which should be copied into the distribution folder. """ items = EricDirFileDialog.getOpenFileAndDirNames( - self, - self.tr("Select files and folders"), - self.__project.getProjectPath()) - + self, self.tr("Select files and folders"), self.__project.getProjectPath() + ) + for itm in items: itm = self.__project.getRelativePath(itm) self.fileOrFolderList.addItem(Utilities.toNativeSeparators(itm)) row = self.fileOrFolderList.currentRow() self.on_fileOrFolderList_currentRowChanged(row) - + def accept(self): """ Public method called by the Ok button. - + It saves the values in the parameters dictionary. """ # get data of general tab - self.__parameters['targetDirectory'] = self.__project.getRelativePath( - self.targetDirPicker.text()) - self.__parameters['targetName'] = self.targetNameEdit.text() - self.__parameters['baseName'] = self.basenameCombo.currentText() - self.__parameters['initScript'] = self.initscriptCombo.currentText() - self.__parameters['applicationIcon'] = self.__project.getRelativePath( - self.applicationIconPicker.text()) - self.__parameters['script'] = self.cxfreezeExecCombo.currentText() - self.__parameters['keepPath'] = self.keeppathCheckBox.isChecked() - self.__parameters['compress'] = self.compressCheckBox.isChecked() + self.__parameters["targetDirectory"] = self.__project.getRelativePath( + self.targetDirPicker.text() + ) + self.__parameters["targetName"] = self.targetNameEdit.text() + self.__parameters["baseName"] = self.basenameCombo.currentText() + self.__parameters["initScript"] = self.initscriptCombo.currentText() + self.__parameters["applicationIcon"] = self.__project.getRelativePath( + self.applicationIconPicker.text() + ) + self.__parameters["script"] = self.cxfreezeExecCombo.currentText() + self.__parameters["keepPath"] = self.keeppathCheckBox.isChecked() + self.__parameters["compress"] = self.compressCheckBox.isChecked() if self.nooptimizeRadioButton.isChecked(): - self.__parameters['optimize'] = 0 + self.__parameters["optimize"] = 0 elif self.optimizeRadioButton.isChecked(): - self.__parameters['optimize'] = 1 + self.__parameters["optimize"] = 1 else: - self.__parameters['optimize'] = 2 - + self.__parameters["optimize"] = 2 + # get data of advanced tab - self.__parameters['defaultPath'] = self.__splitIt( - self.defaultPathEdit.text(), os.pathsep) - self.__parameters['includePath'] = self.__splitIt( - self.includePathEdit.text(), os.pathsep) - self.__parameters['replacePaths'] = self.__splitIt( - self.replacePathsEdit.text(), os.pathsep) - self.__parameters['includeModules'] = self.__splitIt( - self.includeModulesEdit.text(), ',') - self.__parameters['excludeModules'] = self.__splitIt( - self.excludeModulesEdit.text(), ',') - self.__parameters['extListFile'] = self.__project.getRelativePath( - self.extListFilePicker.text()) - + self.__parameters["defaultPath"] = self.__splitIt( + self.defaultPathEdit.text(), os.pathsep + ) + self.__parameters["includePath"] = self.__splitIt( + self.includePathEdit.text(), os.pathsep + ) + self.__parameters["replacePaths"] = self.__splitIt( + self.replacePathsEdit.text(), os.pathsep + ) + self.__parameters["includeModules"] = self.__splitIt( + self.includeModulesEdit.text(), "," + ) + self.__parameters["excludeModules"] = self.__splitIt( + self.excludeModulesEdit.text(), "," + ) + self.__parameters["extListFile"] = self.__project.getRelativePath( + self.extListFilePicker.text() + ) + # get data of the additional files tab - additionalFiles = [self.fileOrFolderList.item(x).text() - for x in range(self.fileOrFolderList.count())] - self.__parameters['additionalFiles'] = additionalFiles + additionalFiles = [ + self.fileOrFolderList.item(x).text() + for x in range(self.fileOrFolderList.count()) + ] + self.__parameters["additionalFiles"] = additionalFiles # call the accept slot of the base class QDialog.accept(self) @@ -470,7 +456,7 @@ def __splitIt(self, s, sep): """ Private method to split a string observing various conditions. - + @param s string to split @type str @param sep separator string @@ -480,8 +466,8 @@ """ if s == "" or s is None: return [] - + if s.endswith(sep): s = s[:-1] - + return s.split(sep)