40 @param parent reference to the parent widget |
42 @param parent reference to the parent widget |
41 @type QWidget |
43 @type QWidget |
42 """ |
44 """ |
43 super().__init__(parent) |
45 super().__init__(parent) |
44 self.setupUi(self) |
46 self.setupUi(self) |
45 |
47 |
46 self.__project = project |
48 self.__project = project |
47 self.__mode = mode |
49 self.__mode = mode |
48 |
50 |
49 self.inputFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) |
51 self.inputFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) |
50 self.inputFilePicker.setDefaultDirectory( |
52 self.inputFilePicker.setDefaultDirectory(self.__project.getProjectPath()) |
51 self.__project.getProjectPath()) |
|
52 if self.__mode == "installer": |
53 if self.__mode == "installer": |
53 self.inputFilePicker.setFilters(self.tr( |
54 self.inputFilePicker.setFilters( |
54 "Python Files (*.py *.py3);;" |
55 self.tr( |
55 "Python GUI Files (*.pyw *.pyw3);;" |
56 "Python Files (*.py *.py3);;" |
56 "Spec Files (*.spec);;" |
57 "Python GUI Files (*.pyw *.pyw3);;" |
57 "All Files (*)" |
58 "Spec Files (*.spec);;" |
58 )) |
59 "All Files (*)" |
|
60 ) |
|
61 ) |
59 elif self.__mode == "spec": |
62 elif self.__mode == "spec": |
60 self.inputFilePicker.setFilters(self.tr( |
63 self.inputFilePicker.setFilters( |
61 "Python Files (*.py *.py3);;" |
64 self.tr( |
62 "Python GUI Files (*.pyw *.pyw3);;" |
65 "Python Files (*.py *.py3);;" |
63 "All Files (*)" |
66 "Python GUI Files (*.pyw *.pyw3);;" |
64 )) |
67 "All Files (*)" |
65 |
68 ) |
|
69 ) |
|
70 |
66 self.executableCombo.addItems(executables) |
71 self.executableCombo.addItems(executables) |
67 |
72 |
68 if not bool(project.getMainScript()): |
73 if not bool(project.getMainScript()): |
69 # no main script defined |
74 # no main script defined |
70 self.selectedScriptButton.setChecked(True) |
75 self.selectedScriptButton.setChecked(True) |
71 self.mainScriptButton.setEnabled(False) |
76 self.mainScriptButton.setEnabled(False) |
72 |
77 |
73 self.iconFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) |
78 self.iconFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) |
74 self.iconFilePicker.setDefaultDirectory( |
79 self.iconFilePicker.setDefaultDirectory(self.__project.getProjectPath()) |
75 self.__project.getProjectPath()) |
|
76 if Globals.isMacPlatform(): |
80 if Globals.isMacPlatform(): |
77 self.iconFilePicker.setFilters(self.tr( |
81 self.iconFilePicker.setFilters( |
78 "Icon Files (*.icns);;" |
82 self.tr("Icon Files (*.icns);;" "All Files (*)") |
79 "All Files (*)" |
83 ) |
80 )) |
|
81 elif Globals.isWindowsPlatform(): |
84 elif Globals.isWindowsPlatform(): |
82 self.iconFilePicker.setFilters(self.tr( |
85 self.iconFilePicker.setFilters( |
83 "Icon Files (*.ico);;" |
86 self.tr( |
84 "Executable Files (*.exe);;" |
87 "Icon Files (*.ico);;" "Executable Files (*.exe);;" "All Files (*)" |
85 "All Files (*)" |
88 ) |
86 )) |
89 ) |
87 |
90 |
88 # disable platform specific tabs |
91 # disable platform specific tabs |
89 self.tabWidget.setTabEnabled( |
92 self.tabWidget.setTabEnabled( |
90 self.tabWidget.indexOf(self.windowsMacTab), |
93 self.tabWidget.indexOf(self.windowsMacTab), |
91 Globals.isMacPlatform() or Globals.isWindowsPlatform()) |
94 Globals.isMacPlatform() or Globals.isWindowsPlatform(), |
|
95 ) |
92 self.tabWidget.setTabEnabled( |
96 self.tabWidget.setTabEnabled( |
93 self.tabWidget.indexOf(self.macTab), |
97 self.tabWidget.indexOf(self.macTab), Globals.isMacPlatform() |
94 Globals.isMacPlatform()) |
98 ) |
95 |
99 |
96 self.__initializeDefaults() |
100 self.__initializeDefaults() |
97 |
101 |
98 # get a copy of the defaults to store the user settings |
102 # get a copy of the defaults to store the user settings |
99 self.__parameters = copy.deepcopy(self.__defaults) |
103 self.__parameters = copy.deepcopy(self.__defaults) |
100 |
104 |
101 # combine it with the values of params |
105 # combine it with the values of params |
102 if params is not None: |
106 if params is not None: |
103 self.__parameters.update(params) |
107 self.__parameters.update(params) |
104 |
108 |
105 # initialize general tab |
109 # initialize general tab |
106 if mode == "installer" and bool(self.__parameters["pyinstaller"]): |
110 if mode == "installer" and bool(self.__parameters["pyinstaller"]): |
107 self.executableCombo.setCurrentIndex( |
111 self.executableCombo.setCurrentIndex( |
108 self.executableCombo.findText( |
112 self.executableCombo.findText(self.__parameters["pyinstaller"]) |
109 self.__parameters["pyinstaller"])) |
113 ) |
110 elif mode == "spec" and bool(self.__parameters["pyi-makespec"]): |
114 elif mode == "spec" and bool(self.__parameters["pyi-makespec"]): |
111 self.executableCombo.setCurrentIndex( |
115 self.executableCombo.setCurrentIndex( |
112 self.executableCombo.findText( |
116 self.executableCombo.findText(self.__parameters["pyi-makespec"]) |
113 self.__parameters["pyi-makespec"])) |
117 ) |
114 if self.__parameters["mainscript"]: |
118 if self.__parameters["mainscript"]: |
115 self.mainScriptButton.setChecked(True) |
119 self.mainScriptButton.setChecked(True) |
116 else: |
120 else: |
117 self.selectedScriptButton.setChecked(True) |
121 self.selectedScriptButton.setChecked(True) |
118 self.inputFilePicker.setText(self.__parameters["inputFile"]) |
122 self.inputFilePicker.setText(self.__parameters["inputFile"]) |
155 "inputFile": "", |
158 "inputFile": "", |
156 "oneDirectory": True, |
159 "oneDirectory": True, |
157 "name": "", |
160 "name": "", |
158 "encryptionKey": "", |
161 "encryptionKey": "", |
159 "cleanBeforeBuilding": False, |
162 "cleanBeforeBuilding": False, |
160 |
|
161 # Windows and macOS options |
163 # Windows and macOS options |
162 "consoleApplication": True, |
164 "consoleApplication": True, |
163 "iconFile": "", |
165 "iconFile": "", |
164 "iconId": "", |
166 "iconId": "", |
165 |
|
166 # macOS specific options |
167 # macOS specific options |
167 "bundleIdentifier": "", |
168 "bundleIdentifier": "", |
168 } |
169 } |
169 |
170 |
170 def generateParameters(self): |
171 def generateParameters(self): |
171 """ |
172 """ |
172 Public method that generates the command line parameters. |
173 Public method that generates the command line parameters. |
173 |
174 |
174 It generates a list of strings to be used to set the QProcess arguments |
175 It generates a list of strings to be used to set the QProcess arguments |
175 for the pyinstaller/pyi-makespec call and a list containing the non |
176 for the pyinstaller/pyi-makespec call and a list containing the non |
176 default parameters. The second list can be passed back upon object |
177 default parameters. The second list can be passed back upon object |
177 generation to overwrite the default settings. |
178 generation to overwrite the default settings. |
178 |
179 |
179 @return a tuple of the command line parameters, non default parameters |
180 @return a tuple of the command line parameters, non default parameters |
180 and the script path |
181 and the script path |
181 @rtype tuple of (list of str, dict, str) |
182 @rtype tuple of (list of str, dict, str) |
182 """ |
183 """ |
183 parms = {} |
184 parms = {} |
184 args = [] |
185 args = [] |
185 |
186 |
186 # 1. the program name |
187 # 1. the program name |
187 if self.__mode == "installer": |
188 if self.__mode == "installer": |
188 args.append(self.__parameters["pyinstaller"]) |
189 args.append(self.__parameters["pyinstaller"]) |
189 parms["pyinstaller"] = self.__parameters["pyinstaller"] |
190 parms["pyinstaller"] = self.__parameters["pyinstaller"] |
190 elif self.__mode == "spec": |
191 elif self.__mode == "spec": |
191 args.append(self.__parameters["pyi-makespec"]) |
192 args.append(self.__parameters["pyi-makespec"]) |
192 parms["pyi-makespec"] = self.__parameters["pyi-makespec"] |
193 parms["pyi-makespec"] = self.__parameters["pyi-makespec"] |
193 |
194 |
194 # 2. the commandline options |
195 # 2. the commandline options |
195 # 2.1 general options, input |
196 # 2.1 general options, input |
196 if not self.__parameters["mainscript"]: |
197 if not self.__parameters["mainscript"]: |
197 parms["mainscript"] = False |
198 parms["mainscript"] = False |
198 parms["inputFile"] = self.__parameters["inputFile"] |
199 parms["inputFile"] = self.__parameters["inputFile"] |
199 |
200 |
200 runWithSpec = self.__parameters["inputFile"].endswith(".spec") |
201 runWithSpec = self.__parameters["inputFile"].endswith(".spec") |
201 if not runWithSpec: |
202 if not runWithSpec: |
202 # 2.2 general options, part 1 |
203 # 2.2 general options, part 1 |
203 if not self.__parameters["oneDirectory"]: |
204 if not self.__parameters["oneDirectory"]: |
204 parms["oneDirectory"] = self.__parameters["oneDirectory"] |
205 parms["oneDirectory"] = self.__parameters["oneDirectory"] |
205 args.append("--onefile") |
206 args.append("--onefile") |
206 if self.__parameters["name"] != self.__defaults["name"]: |
207 if self.__parameters["name"] != self.__defaults["name"]: |
207 parms["name"] = self.__parameters["name"] |
208 parms["name"] = self.__parameters["name"] |
208 args.append("--name") |
209 args.append("--name") |
209 args.append(self.__parameters["name"]) |
210 args.append(self.__parameters["name"]) |
210 if ( |
211 if self.__parameters["encryptionKey"] != self.__defaults["encryptionKey"]: |
211 self.__parameters["encryptionKey"] != |
|
212 self.__defaults["encryptionKey"] |
|
213 ): |
|
214 parms["encryptionKey"] = self.__parameters["encryptionKey"] |
212 parms["encryptionKey"] = self.__parameters["encryptionKey"] |
215 args.append("--key") |
213 args.append("--key") |
216 args.append(self.__parameters["encryptionKey"]) |
214 args.append(self.__parameters["encryptionKey"]) |
217 |
215 |
218 # 2.3 Windows and macOS options |
216 # 2.3 Windows and macOS options |
219 if ( |
217 if ( |
220 self.__parameters["consoleApplication"] != |
218 self.__parameters["consoleApplication"] |
221 self.__defaults["consoleApplication"] |
219 != self.__defaults["consoleApplication"] |
222 ): |
220 ): |
223 parms["consoleApplication"] = ( |
221 parms["consoleApplication"] = self.__parameters["consoleApplication"] |
224 self.__parameters["consoleApplication"] |
|
225 ) |
|
226 args.append("--windowed") |
222 args.append("--windowed") |
227 if self.__parameters["iconFile"] != self.__defaults["iconFile"]: |
223 if self.__parameters["iconFile"] != self.__defaults["iconFile"]: |
228 parms["iconFile"] = self.__parameters["iconFile"] |
224 parms["iconFile"] = self.__parameters["iconFile"] |
229 parms["iconId"] = self.__parameters["iconId"] |
225 parms["iconId"] = self.__parameters["iconId"] |
230 args.append("--icon") |
226 args.append("--icon") |
231 if self.__parameters["iconFile"].endswith(".exe"): |
227 if self.__parameters["iconFile"].endswith(".exe"): |
232 if bool(self.__parameters["iconId"]): |
228 if bool(self.__parameters["iconId"]): |
233 iconId = self.__parameters["iconId"] |
229 iconId = self.__parameters["iconId"] |
234 else: |
230 else: |
235 iconId = "0" |
231 iconId = "0" |
236 args.append("{0},{1}".format( |
232 args.append("{0},{1}".format(self.__parameters["iconFile"], iconId)) |
237 self.__parameters["iconFile"], iconId)) |
|
238 else: |
233 else: |
239 args.append(self.__parameters["iconFile"]) |
234 args.append(self.__parameters["iconFile"]) |
240 |
235 |
241 # 2.4 macOS specific options |
236 # 2.4 macOS specific options |
242 if ( |
237 if ( |
243 self.__parameters["bundleIdentifier"] != |
238 self.__parameters["bundleIdentifier"] |
244 self.__defaults["bundleIdentifier"] |
239 != self.__defaults["bundleIdentifier"] |
245 ): |
240 ): |
246 parms["bundleIdentifier"] = ( |
241 parms["bundleIdentifier"] = self.__parameters["bundleIdentifier"] |
247 self.__parameters["bundleIdentifier"] |
|
248 ) |
|
249 args.append("--osx-bundle-identifier") |
242 args.append("--osx-bundle-identifier") |
250 args.append(self.__parameters["bundleIdentifier"]) |
243 args.append(self.__parameters["bundleIdentifier"]) |
251 |
244 |
252 # 2.5 general options, part 2 |
245 # 2.5 general options, part 2 |
253 if ( |
246 if ( |
254 self.__parameters["cleanBeforeBuilding"] != |
247 self.__parameters["cleanBeforeBuilding"] |
255 self.__defaults["cleanBeforeBuilding"] |
248 != self.__defaults["cleanBeforeBuilding"] |
256 ): |
249 ): |
257 parms["cleanBeforeBuilding"] = ( |
250 parms["cleanBeforeBuilding"] = self.__parameters["cleanBeforeBuilding"] |
258 self.__parameters["cleanBeforeBuilding"] |
|
259 ) |
|
260 args.append("--clean") |
251 args.append("--clean") |
261 |
252 |
262 # 3. always add these arguments |
253 # 3. always add these arguments |
263 if self.__mode == "installer": |
254 if self.__mode == "installer": |
264 args.append("--noconfirm") # don't ask the user |
255 args.append("--noconfirm") # don't ask the user |
265 |
256 |
266 # determine the script to be processed |
257 # determine the script to be processed |
267 script = ( |
258 script = ( |
268 self.__project.getMainScript() |
259 self.__project.getMainScript() |
269 if self.__parameters["mainscript"] else |
260 if self.__parameters["mainscript"] |
270 self.__parameters["inputFile"] |
261 else self.__parameters["inputFile"] |
271 ) |
262 ) |
272 |
263 |
273 return args, parms, script |
264 return args, parms, script |
274 |
265 |
275 def accept(self): |
266 def accept(self): |
276 """ |
267 """ |
277 Public method called by the Ok button. |
268 Public method called by the Ok button. |
278 |
269 |
279 It saves the values in the parameters dictionary. |
270 It saves the values in the parameters dictionary. |
280 """ |
271 """ |
281 # get data of general tab |
272 # get data of general tab |
282 if self.__mode == "installer": |
273 if self.__mode == "installer": |
283 self.__parameters["pyinstaller"] = ( |
274 self.__parameters["pyinstaller"] = self.executableCombo.currentText() |
284 self.executableCombo.currentText() |
|
285 ) |
|
286 elif self.__mode == "spec": |
275 elif self.__mode == "spec": |
287 self.__parameters["pyi-makespec"] = ( |
276 self.__parameters["pyi-makespec"] = self.executableCombo.currentText() |
288 self.executableCombo.currentText() |
|
289 ) |
|
290 self.__parameters["mainscript"] = self.mainScriptButton.isChecked() |
277 self.__parameters["mainscript"] = self.mainScriptButton.isChecked() |
291 self.__parameters["inputFile"] = self.inputFilePicker.text() |
278 self.__parameters["inputFile"] = self.inputFilePicker.text() |
292 self.__parameters["oneDirectory"] = self.oneDirButton.isChecked() |
279 self.__parameters["oneDirectory"] = self.oneDirButton.isChecked() |
293 self.__parameters["name"] = self.nameEdit.text() |
280 self.__parameters["name"] = self.nameEdit.text() |
294 self.__parameters["encryptionKey"] = self.keyEdit.text() |
281 self.__parameters["encryptionKey"] = self.keyEdit.text() |
295 self.__parameters["cleanBeforeBuilding"] = ( |
282 self.__parameters["cleanBeforeBuilding"] = self.cleanCheckBox.isChecked() |
296 self.cleanCheckBox.isChecked() |
283 |
297 ) |
|
298 |
|
299 # get data of Windows and macOS tab |
284 # get data of Windows and macOS tab |
300 self.__parameters["consoleApplication"] = ( |
285 self.__parameters["consoleApplication"] = self.consoleButton.isChecked() |
301 self.consoleButton.isChecked() |
|
302 ) |
|
303 self.__parameters["iconFile"] = self.iconFilePicker.text() |
286 self.__parameters["iconFile"] = self.iconFilePicker.text() |
304 self.__parameters["iconId"] = self.iconIdEdit.text() |
287 self.__parameters["iconId"] = self.iconIdEdit.text() |
305 |
288 |
306 # get data of macOS specific tab |
289 # get data of macOS specific tab |
307 self.__parameters["bundleIdentifier"] = ( |
290 self.__parameters["bundleIdentifier"] = self.bundleIdentifierEdit.text() |
308 self.bundleIdentifierEdit.text() |
|
309 ) |
|
310 |
291 |
311 # call the accept slot of the base class |
292 # call the accept slot of the base class |
312 super().accept() |
293 super().accept() |
313 |
294 |
314 def __updateOkButton(self): |
295 def __updateOkButton(self): |
315 """ |
296 """ |
316 Private method to update the enabled state of the OK button. |
297 Private method to update the enabled state of the OK button. |
317 """ |
298 """ |
318 enable = True |
299 enable = True |
319 |
300 |
320 # If not to be run with the project main script, a script or |
301 # If not to be run with the project main script, a script or |
321 # spec file must be selected. |
302 # spec file must be selected. |
322 if ( |
303 if self.selectedScriptButton.isChecked() and not bool( |
323 self.selectedScriptButton.isChecked() and |
304 self.inputFilePicker.text() |
324 not bool(self.inputFilePicker.text()) |
|
325 ): |
305 ): |
326 enable = False |
306 enable = False |
327 |
307 |
328 # If the icon shall be picked from a .exe file, an icon ID |
308 # If the icon shall be picked from a .exe file, an icon ID |
329 # must be entered (Windows only). |
309 # must be entered (Windows only). |
330 if ( |
310 if self.iconFilePicker.text().endswith(".exe") and not bool( |
331 self.iconFilePicker.text().endswith(".exe") and |
311 self.iconIdEdit.text() |
332 not bool(self.iconIdEdit.text()) |
|
333 ): |
312 ): |
334 enable = False |
313 enable = False |
335 |
314 |
336 self.buttonBox.button( |
315 self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(enable) |
337 QDialogButtonBox.StandardButton.Ok).setEnabled(enable) |
316 |
338 |
|
339 @pyqtSlot(bool) |
317 @pyqtSlot(bool) |
340 def on_selectedScriptButton_toggled(self, checked): |
318 def on_selectedScriptButton_toggled(self, checked): |
341 """ |
319 """ |
342 Private slot to handle changes of the radio button state. |
320 Private slot to handle changes of the radio button state. |
343 |
321 |
344 @param checked state of the radio button |
322 @param checked state of the radio button |
345 @type bool |
323 @type bool |
346 """ |
324 """ |
347 self.__updateOkButton() |
325 self.__updateOkButton() |
348 |
326 |
349 @pyqtSlot(str) |
327 @pyqtSlot(str) |
350 def on_inputFilePicker_textChanged(self, txt): |
328 def on_inputFilePicker_textChanged(self, txt): |
351 """ |
329 """ |
352 Private slot to handle changes of the input file. |
330 Private slot to handle changes of the input file. |
353 |
331 |
354 @param txt text of the file edit |
332 @param txt text of the file edit |
355 @type str |
333 @type str |
356 """ |
334 """ |
357 self.__updateOkButton() |
335 self.__updateOkButton() |
358 |
336 |
359 @pyqtSlot(str) |
337 @pyqtSlot(str) |
360 def on_iconFilePicker_textChanged(self, txt): |
338 def on_iconFilePicker_textChanged(self, txt): |
361 """ |
339 """ |
362 Private slot to handle changes of the icon file. |
340 Private slot to handle changes of the icon file. |
363 |
341 |
364 @param txt text of the file edit |
342 @param txt text of the file edit |
365 @type str |
343 @type str |
366 """ |
344 """ |
367 self.iconIdEdit.setEnabled(txt.endswith(".exe")) |
345 self.iconIdEdit.setEnabled(txt.endswith(".exe")) |
368 self.__updateOkButton() |
346 self.__updateOkButton() |
369 |
347 |
370 @pyqtSlot(str) |
348 @pyqtSlot(str) |
371 def on_iconIdEdit_textChanged(self, txt): |
349 def on_iconIdEdit_textChanged(self, txt): |
372 """ |
350 """ |
373 Private slot to handle changes of the icon ID. |
351 Private slot to handle changes of the icon ID. |
374 |
352 |
375 @param txt iconID |
353 @param txt iconID |
376 @type str |
354 @type str |
377 """ |
355 """ |
378 self.__updateOkButton() |
356 self.__updateOkButton() |