|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2003 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing the file dialog wizard dialog. |
|
8 """ |
|
9 |
|
10 from __future__ import unicode_literals |
|
11 |
|
12 import os |
|
13 |
|
14 from PyQt5.QtCore import pyqtSlot |
|
15 from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QFileDialog, \ |
|
16 QButtonGroup |
|
17 |
|
18 from E5Gui.E5Completers import E5FileCompleter, E5DirCompleter |
|
19 |
|
20 from .Ui_FileDialogWizardDialog import Ui_FileDialogWizardDialog |
|
21 |
|
22 import Globals |
|
23 |
|
24 |
|
25 class FileDialogWizardDialog(QDialog, Ui_FileDialogWizardDialog): |
|
26 """ |
|
27 Class implementing the color dialog wizard dialog. |
|
28 |
|
29 It displays a dialog for entering the parameters |
|
30 for the QFileDialog code generator. |
|
31 """ |
|
32 def __init__(self, pyqtVariant, parent=None): |
|
33 """ |
|
34 Constructor |
|
35 |
|
36 @param pyqtVariant variant of PyQt (integer; 0, 4 or 5) |
|
37 @param parent parent widget (QWidget) |
|
38 """ |
|
39 super(FileDialogWizardDialog, self).__init__(parent) |
|
40 self.setupUi(self) |
|
41 |
|
42 self.eStartWithCompleter = E5FileCompleter(self.eStartWith) |
|
43 self.eWorkDirCompleter = E5DirCompleter(self.eWorkDir) |
|
44 |
|
45 self.__pyqtVariant = pyqtVariant |
|
46 |
|
47 self.__typeButtonsGroup = QButtonGroup(self) |
|
48 self.__typeButtonsGroup.setExclusive(True) |
|
49 self.__typeButtonsGroup.addButton(self.rOpenFile, 1) |
|
50 self.__typeButtonsGroup.addButton(self.rOpenFiles, 2) |
|
51 self.__typeButtonsGroup.addButton(self.rSaveFile, 3) |
|
52 self.__typeButtonsGroup.addButton(self.rfOpenFile, 11) |
|
53 self.__typeButtonsGroup.addButton(self.rfOpenFiles, 12) |
|
54 self.__typeButtonsGroup.addButton(self.rfSaveFile, 13) |
|
55 self.__typeButtonsGroup.addButton(self.rDirectory, 20) |
|
56 self.__typeButtonsGroup.buttonClicked[int].connect( |
|
57 self.__toggleInitialFilterAndResult) |
|
58 self.__toggleInitialFilterAndResult(1) |
|
59 |
|
60 self.pyqtComboBox.addItems(["PyQt4", "PyQt5"]) |
|
61 self.__pyqtVariant = pyqtVariant |
|
62 if self.__pyqtVariant == 5: |
|
63 self.pyqtComboBox.setCurrentIndex(1) |
|
64 else: |
|
65 self.pyqtComboBox.setCurrentIndex(0) |
|
66 |
|
67 self.rSaveFile.toggled[bool].connect(self.__toggleConfirmCheckBox) |
|
68 self.rfSaveFile.toggled[bool].connect(self.__toggleConfirmCheckBox) |
|
69 self.rDirectory.toggled[bool].connect(self.__toggleGroupsAndTest) |
|
70 self.cStartWith.toggled[bool].connect(self.__toggleGroupsAndTest) |
|
71 self.cWorkDir.toggled[bool].connect(self.__toggleGroupsAndTest) |
|
72 self.cFilters.toggled[bool].connect(self.__toggleGroupsAndTest) |
|
73 |
|
74 self.bTest = self.buttonBox.addButton( |
|
75 self.tr("Test"), QDialogButtonBox.ActionRole) |
|
76 |
|
77 msh = self.minimumSizeHint() |
|
78 self.resize(max(self.width(), msh.width()), msh.height()) |
|
79 |
|
80 def __adjustOptions(self, options): |
|
81 """ |
|
82 Private method to adjust the file dialog options. |
|
83 |
|
84 @param options file dialog options (QFileDialog.Options) |
|
85 @return modified options (QFileDialog.Options) |
|
86 """ |
|
87 if Globals.isLinuxPlatform(): |
|
88 options |= QFileDialog.DontUseNativeDialog |
|
89 return options |
|
90 |
|
91 @pyqtSlot(str) |
|
92 def on_pyqtComboBox_currentIndexChanged(self, txt): |
|
93 """ |
|
94 Private slot to setup the dialog for the selected PyQt variant. |
|
95 |
|
96 @param txt text of the selected combo box entry (string) |
|
97 """ |
|
98 self.rfOpenFile.setEnabled(txt == "PyQt4") |
|
99 self.rfOpenFiles.setEnabled(txt == "PyQt4") |
|
100 self.rfSaveFile.setEnabled(txt == "PyQt4") |
|
101 |
|
102 if txt == "PyQt5": |
|
103 if self.rfOpenFile.isChecked(): |
|
104 self.rOpenFile.setChecked(True) |
|
105 elif self.rfOpenFiles.isChecked(): |
|
106 self.rOpenFiles.setChecked(True) |
|
107 elif self.rfSaveFile.isChecked(): |
|
108 self.rSaveFile.setChecked(True) |
|
109 |
|
110 self.__pyqtVariant = 5 if txt == "PyQt5" else 4 |
|
111 |
|
112 self.__toggleInitialFilterAndResult( |
|
113 self.__typeButtonsGroup.checkedId()) |
|
114 |
|
115 def on_buttonBox_clicked(self, button): |
|
116 """ |
|
117 Private slot called by a button of the button box clicked. |
|
118 |
|
119 @param button button that was clicked (QAbstractButton) |
|
120 """ |
|
121 if button == self.bTest: |
|
122 self.on_bTest_clicked() |
|
123 |
|
124 @pyqtSlot() |
|
125 def on_bTest_clicked(self): |
|
126 """ |
|
127 Private method to test the selected options. |
|
128 """ |
|
129 if self.rOpenFile.isChecked() or self.rfOpenFile.isChecked(): |
|
130 if not self.cSymlinks.isChecked(): |
|
131 options = QFileDialog.Options(QFileDialog.DontResolveSymlinks) |
|
132 else: |
|
133 options = QFileDialog.Options() |
|
134 options = self.__adjustOptions(options) |
|
135 if self.rOpenFile.isChecked() and self.__pyqtVariant == 4: |
|
136 try: |
|
137 QFileDialog.getOpenFileName( |
|
138 None, |
|
139 self.eCaption.text(), |
|
140 self.eStartWith.text(), |
|
141 self.eFilters.text(), |
|
142 options) |
|
143 except TypeError: |
|
144 QFileDialog.getOpenFileName( |
|
145 None, |
|
146 self.eCaption.text(), |
|
147 self.eStartWith.text(), |
|
148 self.eFilters.text(), |
|
149 self.eInitialFilter.text(), |
|
150 options) |
|
151 else: |
|
152 try: |
|
153 QFileDialog.getOpenFileNameAndFilter( |
|
154 None, |
|
155 self.eCaption.text(), |
|
156 self.eStartWith.text(), |
|
157 self.eFilters.text(), |
|
158 self.eInitialFilter.text(), |
|
159 options) |
|
160 except AttributeError: |
|
161 QFileDialog.getOpenFileName( |
|
162 None, |
|
163 self.eCaption.text(), |
|
164 self.eStartWith.text(), |
|
165 self.eFilters.text(), |
|
166 self.eInitialFilter.text(), |
|
167 options) |
|
168 elif self.rOpenFiles.isChecked() or self.rfOpenFiles.isChecked(): |
|
169 if not self.cSymlinks.isChecked(): |
|
170 options = QFileDialog.Options(QFileDialog.DontResolveSymlinks) |
|
171 else: |
|
172 options = QFileDialog.Options() |
|
173 options = self.__adjustOptions(options) |
|
174 if self.rOpenFiles.isChecked() and self.__pyqtVariant == 4: |
|
175 try: |
|
176 QFileDialog.getOpenFileNames( |
|
177 None, |
|
178 self.eCaption.text(), |
|
179 self.eStartWith.text(), |
|
180 self.eFilters.text(), |
|
181 options) |
|
182 except TypeError: |
|
183 QFileDialog.getOpenFileNames( |
|
184 None, |
|
185 self.eCaption.text(), |
|
186 self.eStartWith.text(), |
|
187 self.eFilters.text(), |
|
188 self.eInitialFilter.text(), |
|
189 options) |
|
190 else: |
|
191 try: |
|
192 QFileDialog.getOpenFileNamesAndFilter( |
|
193 None, |
|
194 self.eCaption.text(), |
|
195 self.eStartWith.text(), |
|
196 self.eFilters.text(), |
|
197 self.eInitialFilter.text(), |
|
198 options) |
|
199 except AttributeError: |
|
200 QFileDialog.getOpenFileNames( |
|
201 None, |
|
202 self.eCaption.text(), |
|
203 self.eStartWith.text(), |
|
204 self.eFilters.text(), |
|
205 self.eInitialFilter.text(), |
|
206 options) |
|
207 elif self.rSaveFile.isChecked() or self.rfSaveFile.isChecked(): |
|
208 if not self.cSymlinks.isChecked(): |
|
209 options = QFileDialog.Options(QFileDialog.DontResolveSymlinks) |
|
210 else: |
|
211 options = QFileDialog.Options() |
|
212 options = self.__adjustOptions(options) |
|
213 if self.rSaveFile.isChecked() and self.__pyqtVariant == 4: |
|
214 try: |
|
215 QFileDialog.getSaveFileName( |
|
216 None, |
|
217 self.eCaption.text(), |
|
218 self.eStartWith.text(), |
|
219 self.eFilters.text(), |
|
220 options) |
|
221 except TypeError: |
|
222 QFileDialog.getSaveFileName( |
|
223 None, |
|
224 self.eCaption.text(), |
|
225 self.eStartWith.text(), |
|
226 self.eFilters.text(), |
|
227 self.eInitialFilter.text(), |
|
228 options) |
|
229 else: |
|
230 try: |
|
231 QFileDialog.getSaveFileNameAndFilter( |
|
232 None, |
|
233 self.eCaption.text(), |
|
234 self.eStartWith.text(), |
|
235 self.eFilters.text(), |
|
236 self.eInitialFilter.text(), |
|
237 options) |
|
238 except AttributeError: |
|
239 QFileDialog.getSaveFileName( |
|
240 None, |
|
241 self.eCaption.text(), |
|
242 self.eStartWith.text(), |
|
243 self.eFilters.text(), |
|
244 self.eInitialFilter.text(), |
|
245 options) |
|
246 elif self.rDirectory.isChecked(): |
|
247 options = QFileDialog.Options() |
|
248 if not self.cSymlinks.isChecked(): |
|
249 options |= QFileDialog.Options(QFileDialog.DontResolveSymlinks) |
|
250 if self.cDirOnly.isChecked(): |
|
251 options |= QFileDialog.Options(QFileDialog.ShowDirsOnly) |
|
252 else: |
|
253 options |= QFileDialog.Options(QFileDialog.Option(0)) |
|
254 options = self.__adjustOptions(options) |
|
255 QFileDialog.getExistingDirectory( |
|
256 None, |
|
257 self.eCaption.text(), |
|
258 self.eWorkDir.text(), |
|
259 options) |
|
260 |
|
261 def __toggleConfirmCheckBox(self): |
|
262 """ |
|
263 Private slot to enable/disable the confirmation check box. |
|
264 """ |
|
265 self.cConfirmOverwrite.setEnabled( |
|
266 self.rSaveFile.isChecked() or self.rfSaveFile.isChecked()) |
|
267 |
|
268 def __toggleGroupsAndTest(self): |
|
269 """ |
|
270 Private slot to enable/disable certain groups and the test button. |
|
271 """ |
|
272 if self.rDirectory.isChecked(): |
|
273 self.filePropertiesGroup.setEnabled(False) |
|
274 self.dirPropertiesGroup.setEnabled(True) |
|
275 self.bTest.setDisabled(self.cWorkDir.isChecked()) |
|
276 else: |
|
277 self.filePropertiesGroup.setEnabled(True) |
|
278 self.dirPropertiesGroup.setEnabled(False) |
|
279 self.bTest.setDisabled( |
|
280 self.cStartWith.isChecked() or self.cFilters.isChecked()) |
|
281 |
|
282 def __toggleInitialFilterAndResult(self, checkedId): |
|
283 """ |
|
284 Private slot to enable/disable the initial filter elements and the |
|
285 results entries. |
|
286 |
|
287 @param checkedId id of the clicked button (integer) |
|
288 """ |
|
289 if (self.__pyqtVariant == 4 and checkedId in [11, 12, 13]) or \ |
|
290 (self.__pyqtVariant == 5 and checkedId in [1, 2, 3]): |
|
291 enable = True |
|
292 else: |
|
293 enable = False |
|
294 self.lInitialFilter.setEnabled(enable) |
|
295 self.eInitialFilter.setEnabled(enable) |
|
296 self.cInitialFilter.setEnabled(enable) |
|
297 |
|
298 self.lFilterVariable.setEnabled(enable) |
|
299 self.eFilterVariable.setEnabled(enable) |
|
300 |
|
301 def getCode(self, indLevel, indString): |
|
302 """ |
|
303 Public method to get the source code for Qt4 and Qt5. |
|
304 |
|
305 @param indLevel indentation level (int) |
|
306 @param indString string used for indentation (space or tab) (string) |
|
307 @return generated code (string) |
|
308 """ |
|
309 # calculate our indentation level and the indentation string |
|
310 il = indLevel + 1 |
|
311 istring = il * indString |
|
312 estring = os.linesep + indLevel * indString |
|
313 |
|
314 # now generate the code |
|
315 if self.parentSelf.isChecked(): |
|
316 parent = "self" |
|
317 elif self.parentNone.isChecked(): |
|
318 parent = "None" |
|
319 elif self.parentOther.isChecked(): |
|
320 parent = self.parentEdit.text() |
|
321 if parent == "": |
|
322 parent = "None" |
|
323 |
|
324 # prepare the result variables |
|
325 nameVariable = self.eNameVariable.text() |
|
326 if not nameVariable: |
|
327 if self.__typeButtonsGroup.checkedButton() in [ |
|
328 self.rOpenFile, self.rfOpenFile, |
|
329 self.rSaveFile, self.rfSaveFile]: |
|
330 nameVariable = "fileName" |
|
331 elif self.__typeButtonsGroup.checkedButton() in [ |
|
332 self.rOpenFiles, self.rfOpenFiles]: |
|
333 nameVariable = "fileNames" |
|
334 elif self.__typeButtonsGroup.checkedButton() == self.rDirectory: |
|
335 nameVariable = "dirName" |
|
336 else: |
|
337 nameVariable = "res" |
|
338 filterVariable = self.eFilterVariable.text() |
|
339 if not filterVariable: |
|
340 if (self.__pyqtVariant == 4 and |
|
341 self.__typeButtonsGroup.checkedButton() in [ |
|
342 self.rfOpenFile, self.rfOpenFiles, self.rfSaveFile]) or \ |
|
343 (self.__pyqtVariant == 5 and |
|
344 self.__typeButtonsGroup.checkedButton() in [ |
|
345 self.rOpenFile, self.rOpenFiles, self.rSaveFile]): |
|
346 filterVariable = ", selectedFilter" |
|
347 else: |
|
348 filterVariable = "" |
|
349 else: |
|
350 filterVariable = ", " + filterVariable |
|
351 |
|
352 code = '{0}{1} = QFileDialog.'.format(nameVariable, filterVariable) |
|
353 if self.rOpenFile.isChecked() or self.rfOpenFile.isChecked(): |
|
354 if self.rOpenFile.isChecked(): |
|
355 code += 'getOpenFileName({0}{1}'.format(os.linesep, istring) |
|
356 else: |
|
357 code += 'getOpenFileNameAndFilter({0}{1}'.format( |
|
358 os.linesep, istring) |
|
359 code += '{0},{1}{2}'.format(parent, os.linesep, istring) |
|
360 if not self.eCaption.text(): |
|
361 code += '"",{0}{1}'.format(os.linesep, istring) |
|
362 else: |
|
363 code += 'self.tr("{0}"),{1}{2}'.format( |
|
364 self.eCaption.text(), os.linesep, istring) |
|
365 if not self.eStartWith.text(): |
|
366 code += '"",{0}{1}'.format(os.linesep, istring) |
|
367 else: |
|
368 if self.cStartWith.isChecked(): |
|
369 fmt = '{0},{1}{2}' |
|
370 else: |
|
371 fmt = 'self.tr("{0}"),{1}{2}' |
|
372 code += fmt.format(self.eStartWith.text(), os.linesep, istring) |
|
373 if self.eFilters.text() == "": |
|
374 code += '""' |
|
375 else: |
|
376 if self.cFilters.isChecked(): |
|
377 fmt = '{0}' |
|
378 else: |
|
379 fmt = 'self.tr("{0}")' |
|
380 code += fmt.format(self.eFilters.text()) |
|
381 if self.rfOpenFile.isChecked() or self.__pyqtVariant == 5: |
|
382 if self.eInitialFilter.text() == "": |
|
383 initialFilter = "None" |
|
384 else: |
|
385 if self.cInitialFilter.isChecked(): |
|
386 fmt = '{0}' |
|
387 else: |
|
388 fmt = 'self.tr("{0}")' |
|
389 initialFilter = fmt.format(self.eInitialFilter.text()) |
|
390 code += ',{0}{1}{2}'.format(os.linesep, istring, initialFilter) |
|
391 if not self.cSymlinks.isChecked(): |
|
392 code += \ |
|
393 ',{0}{1}QFileDialog.Options(' \ |
|
394 'QFileDialog.DontResolveSymlinks)' \ |
|
395 .format(os.linesep, istring) |
|
396 code += '){0}'.format(estring) |
|
397 elif self.rOpenFiles.isChecked() or self.rfOpenFiles.isChecked(): |
|
398 if self.rOpenFiles.isChecked(): |
|
399 code += 'getOpenFileNames({0}{1}'.format(os.linesep, istring) |
|
400 else: |
|
401 code += 'getOpenFileNamesAndFilter({0}{1}'.format( |
|
402 os.linesep, istring) |
|
403 code += '{0},{1}{2}'.format(parent, os.linesep, istring) |
|
404 if not self.eCaption.text(): |
|
405 code += '"",{0}{1}'.format(os.linesep, istring) |
|
406 else: |
|
407 code += 'self.tr("{0}"),{1}{2}'.format( |
|
408 self.eCaption.text(), os.linesep, istring) |
|
409 if not self.eStartWith.text(): |
|
410 code += '"",{0}{1}'.format(os.linesep, istring) |
|
411 else: |
|
412 if self.cStartWith.isChecked(): |
|
413 fmt = '{0},{1}{2}' |
|
414 else: |
|
415 fmt = 'self.tr("{0}"),{1}{2}' |
|
416 code += fmt.format(self.eStartWith.text(), os.linesep, istring) |
|
417 if not self.eFilters.text(): |
|
418 code += '""' |
|
419 else: |
|
420 if self.cFilters.isChecked(): |
|
421 fmt = '{0}' |
|
422 else: |
|
423 fmt = 'self.tr("{0}")' |
|
424 code += fmt.format(self.eFilters.text()) |
|
425 if self.rfOpenFiles.isChecked() or self.__pyqtVariant == 5: |
|
426 if self.eInitialFilter.text() == "": |
|
427 initialFilter = "None" |
|
428 else: |
|
429 if self.cInitialFilter.isChecked(): |
|
430 fmt = '{0}' |
|
431 else: |
|
432 fmt = 'self.tr("{0}")' |
|
433 initialFilter = fmt.format(self.eInitialFilter.text()) |
|
434 code += ',{0}{1}{2}'.format(os.linesep, istring, initialFilter) |
|
435 if not self.cSymlinks.isChecked(): |
|
436 code += \ |
|
437 ',{0}{1}QFileDialog.Options(' \ |
|
438 'QFileDialog.DontResolveSymlinks)' \ |
|
439 .format(os.linesep, istring) |
|
440 code += '){0}'.format(estring) |
|
441 elif self.rSaveFile.isChecked() or self.rfSaveFile.isChecked(): |
|
442 if self.rSaveFile.isChecked(): |
|
443 code += 'getSaveFileName({0}{1}'.format(os.linesep, istring) |
|
444 else: |
|
445 code += 'getSaveFileNameAndFilter({0}{1}'.format( |
|
446 os.linesep, istring) |
|
447 code += '{0},{1}{2}'.format(parent, os.linesep, istring) |
|
448 if not self.eCaption.text(): |
|
449 code += '"",{0}{1}'.format(os.linesep, istring) |
|
450 else: |
|
451 code += 'self.tr("{0}"),{1}{2}'.format( |
|
452 self.eCaption.text(), os.linesep, istring) |
|
453 if not self.eStartWith.text(): |
|
454 code += '"",{0}{1}'.format(os.linesep, istring) |
|
455 else: |
|
456 if self.cStartWith.isChecked(): |
|
457 fmt = '{0},{1}{2}' |
|
458 else: |
|
459 fmt = 'self.tr("{0}"),{1}{2}' |
|
460 code += fmt.format(self.eStartWith.text(), os.linesep, istring) |
|
461 if not self.eFilters.text(): |
|
462 code += '""' |
|
463 else: |
|
464 if self.cFilters.isChecked(): |
|
465 fmt = '{0}' |
|
466 else: |
|
467 fmt = 'self.tr("{0}")' |
|
468 code += fmt.format(self.eFilters.text()) |
|
469 if self.rfSaveFile.isChecked() or self.__pyqtVariant == 5: |
|
470 if self.eInitialFilter.text() == "": |
|
471 initialFilter = "None" |
|
472 else: |
|
473 if self.cInitialFilter.isChecked(): |
|
474 fmt = '{0}' |
|
475 else: |
|
476 fmt = 'self.tr("{0}")' |
|
477 initialFilter = fmt.format(self.eInitialFilter.text()) |
|
478 code += ',{0}{1}{2}'.format(os.linesep, istring, initialFilter) |
|
479 if (not self.cSymlinks.isChecked()) or \ |
|
480 (not self.cConfirmOverwrite.isChecked()): |
|
481 code += ',{0}{1}QFileDialog.Options('.format( |
|
482 os.linesep, istring) |
|
483 if not self.cSymlinks.isChecked(): |
|
484 code += 'QFileDialog.DontResolveSymlinks' |
|
485 if (not self.cSymlinks.isChecked()) and \ |
|
486 (not self.cConfirmOverwrite.isChecked()): |
|
487 code += ' | ' |
|
488 if not self.cConfirmOverwrite.isChecked(): |
|
489 code += 'QFileDialog.DontConfirmOverwrite' |
|
490 code += ')' |
|
491 code += '){0}'.format(estring) |
|
492 elif self.rDirectory.isChecked(): |
|
493 code += 'getExistingDirectory({0}{1}'.format(os.linesep, istring) |
|
494 code += '{0},{1}{2}'.format(parent, os.linesep, istring) |
|
495 if not self.eCaption.text(): |
|
496 code += '"",{0}{1}'.format(os.linesep, istring) |
|
497 else: |
|
498 code += 'self.tr("{0}"),{1}{2}'.format( |
|
499 self.eCaption.text(), os.linesep, istring) |
|
500 if not self.eWorkDir.text(): |
|
501 code += '""' |
|
502 else: |
|
503 if self.cWorkDir.isChecked(): |
|
504 fmt = '{0}' |
|
505 else: |
|
506 fmt = 'self.tr("{0}")' |
|
507 code += fmt.format(self.eWorkDir.text()) |
|
508 code += ',{0}{1}QFileDialog.Options('.format(os.linesep, istring) |
|
509 if not self.cSymlinks.isChecked(): |
|
510 code += 'QFileDialog.DontResolveSymlinks | ' |
|
511 if self.cDirOnly.isChecked(): |
|
512 code += 'QFileDialog.ShowDirsOnly' |
|
513 else: |
|
514 code += 'QFileDialog.Option(0)' |
|
515 code += ')){0}'.format(estring) |
|
516 |
|
517 return code |