29 class PropertiesDialog(QDialog, Ui_PropertiesDialog): |
29 class PropertiesDialog(QDialog, Ui_PropertiesDialog): |
30 """ |
30 """ |
31 Class implementing the project properties dialog. |
31 Class implementing the project properties dialog. |
32 """ |
32 """ |
33 |
33 |
34 def __init__(self, project, new=True, parent=None, name=None): |
34 def __init__(self, project, new=True, isRemote=False, parent=None, name=None): |
35 """ |
35 """ |
36 Constructor |
36 Constructor |
37 |
37 |
38 @param project reference to the project object |
38 @param project reference to the project object |
39 @type Project |
39 @type Project |
40 @param new flag indicating the generation of a new project |
40 @param new flag indicating the generation of a new project |
41 (defaults to True) |
41 (defaults to True) |
42 @type bool (optional) |
42 @type bool (optional) |
|
43 @param isRemote flag indicating a remote project (defaults to False) |
|
44 @type bool (optional) |
43 @param parent parent widget of this dialog (defaults to None) |
45 @param parent parent widget of this dialog (defaults to None) |
44 @type QWidget (optional) |
46 @type QWidget (optional) |
45 @param name name of this dialog (defaults to None) |
47 @param name name of this dialog (defaults to None) |
46 @type str (optional) |
48 @type str (optional) |
47 """ |
49 """ |
48 super().__init__(parent) |
50 super().__init__(parent) |
49 if name: |
51 if name: |
50 self.setObjectName(name) |
52 self.setObjectName(name) |
51 self.setupUi(self) |
53 self.setupUi(self) |
52 |
54 |
|
55 self.__remoteProject = isRemote |
|
56 self.__remotefsInterface = ( |
|
57 ericApp().getObject("EricServer").getServiceInterface("FileSystem") |
|
58 ) |
|
59 |
53 self.dirPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) |
60 self.dirPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) |
|
61 self.dirPicker.setRemote(isRemote) |
|
62 |
54 self.srcDirPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) |
63 self.srcDirPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) |
|
64 self.srcDirPicker.setRemote(isRemote) |
|
65 |
55 self.mainscriptPicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) |
66 self.mainscriptPicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) |
|
67 self.mainscriptPicker.setRemote(isRemote) |
56 |
68 |
57 self.makeButton.setIcon(EricPixmapCache.getIcon("makefile")) |
69 self.makeButton.setIcon(EricPixmapCache.getIcon("makefile")) |
58 |
70 |
59 self.docstringStyleComboBox.addItem(self.tr("None"), "") |
71 self.docstringStyleComboBox.addItem(self.tr("None"), "") |
60 for docstringType, docstringStyle in sorted(getSupportedDocstringTypes()): |
72 for docstringType, docstringStyle in sorted(getSupportedDocstringTypes()): |
61 self.docstringStyleComboBox.addItem(docstringStyle, docstringType) |
73 self.docstringStyleComboBox.addItem(docstringStyle, docstringType) |
62 |
74 |
63 self.project = project |
75 self.project = project |
64 self.newProject = new |
76 self.newProject = new |
|
77 |
65 self.transPropertiesDlg = None |
78 self.transPropertiesDlg = None |
66 self.spellPropertiesDlg = None |
79 self.spellPropertiesDlg = None |
67 self.makePropertiesDlg = None |
80 self.makePropertiesDlg = None |
68 self.__fileTypesDict = {} |
81 self.__fileTypesDict = {} |
69 |
82 |
70 patterns = [] |
83 if self.__remoteProject: |
71 for pattern, filetype in self.project.getProjectData( |
84 # some stuff is not supported for remote projects |
72 dataKey="FILETYPES" |
85 self.makeCheckBox.setEnabled(False) |
73 ).items(): |
86 self.makeButton.setEnabled(False) |
74 if filetype == "SOURCES": |
87 self.testingFrameworkComboBox.setEnabled(False) |
75 patterns.append(pattern) |
88 self.embeddedVenvCheckBox.setEnabled(False) |
76 filters = self.tr("Source Files ({0});;All Files (*)").format( |
89 self.spellPropertiesButton.setEnabled(False) |
77 " ".join(sorted(patterns)) |
|
78 ) |
|
79 self.mainscriptPicker.setFilters(filters) |
|
80 |
90 |
81 self.languageComboBox.addItems(project.getProgrammingLanguages()) |
91 self.languageComboBox.addItems(project.getProgrammingLanguages()) |
82 |
92 |
83 projectTypes = [] |
93 projectTypes = [] |
84 for projectTypeItem in project.getProjectTypes().items(): |
94 for projectTypeItem in project.getProjectTypes().items(): |
85 projectTypes.append((projectTypeItem[1], projectTypeItem[0])) |
95 projectTypes.append((projectTypeItem[1], projectTypeItem[0])) |
86 self.projectTypeComboBox.clear() |
96 self.projectTypeComboBox.clear() |
87 for projectType in sorted(projectTypes): |
97 for projectType in sorted(projectTypes): |
88 self.projectTypeComboBox.addItem(projectType[0], projectType[1]) |
98 self.projectTypeComboBox.addItem(projectType[0], projectType[1]) |
89 |
99 |
90 ipath = Preferences.getMultiProject("Workspace") or OSUtilities.getHomeDir() |
100 if self.__remoteProject: |
91 self.__initPaths = [ |
101 self.__initPaths = [self.__remotefsInterface.getcwd()] |
92 FileSystemUtilities.fromNativeSeparators(ipath), |
102 else: |
93 FileSystemUtilities.fromNativeSeparators(ipath) + "/", |
103 ipath = Preferences.getMultiProject("Workspace") or OSUtilities.getHomeDir() |
94 ] |
104 self.__initPaths = [ |
|
105 FileSystemUtilities.fromNativeSeparators(ipath), |
|
106 FileSystemUtilities.fromNativeSeparators(ipath) + "/", |
|
107 ] |
95 |
108 |
96 self.licenseComboBox.lineEdit().setClearButtonEnabled(True) |
109 self.licenseComboBox.lineEdit().setClearButtonEnabled(True) |
97 self.__populateLicenseComboBox() |
110 self.__populateLicenseComboBox() |
98 |
111 |
99 if not new: |
112 if not new: |
100 name = os.path.splitext(self.project.pfile)[0] |
113 self.nameEdit.setReadOnly(True) |
101 self.nameEdit.setText(os.path.basename(name)) |
114 self.dirPicker.setReadOnly(True) |
|
115 |
|
116 if self.__remoteProject: |
|
117 name = self.__remotefsInterface.splitext(self.project.pfile)[0] |
|
118 self.nameEdit.setText(self.__remotefsInterface.basename(name)) |
|
119 else: |
|
120 name = os.path.splitext(self.project.pfile)[0] |
|
121 self.nameEdit.setText(os.path.basename(name)) |
102 self.languageComboBox.setCurrentIndex( |
122 self.languageComboBox.setCurrentIndex( |
103 self.languageComboBox.findText( |
123 self.languageComboBox.findText( |
104 self.project.getProjectData(dataKey="PROGLANGUAGE") |
124 self.project.getProjectData(dataKey="PROGLANGUAGE") |
105 ) |
125 ) |
106 ) |
126 ) |
124 self.descriptionEdit.setPlainText( |
144 self.descriptionEdit.setPlainText( |
125 self.project.getProjectData(dataKey="DESCRIPTION") |
145 self.project.getProjectData(dataKey="DESCRIPTION") |
126 ) |
146 ) |
127 self.eolComboBox.setCurrentIndex(self.project.getProjectData(dataKey="EOL")) |
147 self.eolComboBox.setCurrentIndex(self.project.getProjectData(dataKey="EOL")) |
128 self.vcsLabel.show() |
148 self.vcsLabel.show() |
129 if self.project.vcs is not None: |
149 if not self.__remoteProject: |
130 vcsSystemsDict = ( |
150 # VCS not supported for remote projects |
131 ericApp() |
151 if self.project.vcs is not None: |
132 .getObject("PluginManager") |
152 vcsSystemsDict = ( |
133 .getPluginDisplayStrings("version_control") |
153 ericApp() |
|
154 .getObject("PluginManager") |
|
155 .getPluginDisplayStrings("version_control") |
|
156 ) |
|
157 try: |
|
158 vcsSystemDisplay = vcsSystemsDict[ |
|
159 self.project.getProjectData(dataKey="VCS") |
|
160 ] |
|
161 except KeyError: |
|
162 vcsSystemDisplay = "None" |
|
163 self.vcsLabel.setText( |
|
164 self.tr( |
|
165 "The project is version controlled by <b>{0}</b>." |
|
166 ).format(vcsSystemDisplay) |
|
167 ) |
|
168 self.vcsInfoButton.show() |
|
169 else: |
|
170 self.vcsLabel.setText( |
|
171 self.tr("The project is not version controlled.") |
|
172 ) |
|
173 self.vcsInfoButton.hide() |
|
174 else: |
|
175 self.vcsLabel.setText( |
|
176 self.tr("Version control is not available for remote projects.") |
134 ) |
177 ) |
135 try: |
|
136 vcsSystemDisplay = vcsSystemsDict[ |
|
137 self.project.getProjectData(dataKey="VCS") |
|
138 ] |
|
139 except KeyError: |
|
140 vcsSystemDisplay = "None" |
|
141 self.vcsLabel.setText( |
|
142 self.tr("The project is version controlled by <b>{0}</b>.").format( |
|
143 vcsSystemDisplay |
|
144 ) |
|
145 ) |
|
146 self.vcsInfoButton.show() |
|
147 else: |
|
148 self.vcsLabel.setText(self.tr("The project is not version controlled.")) |
|
149 self.vcsInfoButton.hide() |
178 self.vcsInfoButton.hide() |
150 self.vcsCheckBox.hide() |
179 self.vcsCheckBox.hide() |
151 self.makeCheckBox.setChecked( |
180 if self.__remoteProject: |
152 self.project.getProjectData(dataKey="MAKEPARAMS")["MakeEnabled"] |
181 self.makeCheckBox.setChecked(False) |
153 ) |
182 else: |
|
183 self.makeCheckBox.setChecked( |
|
184 self.project.getProjectData(dataKey="MAKEPARAMS")["MakeEnabled"] |
|
185 ) |
154 cindex = self.docstringStyleComboBox.findData( |
186 cindex = self.docstringStyleComboBox.findData( |
155 self.project.getProjectData(dataKey="DOCSTRING") |
187 self.project.getProjectData(dataKey="DOCSTRING") |
156 ) |
188 ) |
157 self.docstringStyleComboBox.setCurrentIndex(cindex) |
189 self.docstringStyleComboBox.setCurrentIndex(cindex) |
158 with contextlib.suppress(KeyError): |
190 if not self.__remoteProject: |
159 cindex = self.testingFrameworkComboBox.findData( |
191 with contextlib.suppress(KeyError): |
160 self.project.getProjectData(dataKey="TESTING_FRAMEWORK") |
192 cindex = self.testingFrameworkComboBox.findData( |
161 ) |
193 self.project.getProjectData(dataKey="TESTING_FRAMEWORK") |
162 self.testingFrameworkComboBox.setCurrentIndex(cindex) |
194 ) |
|
195 self.testingFrameworkComboBox.setCurrentIndex(cindex) |
163 with contextlib.suppress(KeyError): |
196 with contextlib.suppress(KeyError): |
164 self.licenseComboBox.setCurrentText( |
197 self.licenseComboBox.setCurrentText( |
165 self.project.getProjectData(dataKey="LICENSE") |
198 self.project.getProjectData(dataKey="LICENSE") |
166 ) |
199 ) |
167 self.embeddedVenvCheckBox.setChecked( |
200 self.embeddedVenvCheckBox.setChecked( |
174 ) |
207 ) |
175 self.dirPicker.setText(self.__initPaths[0]) |
208 self.dirPicker.setText(self.__initPaths[0]) |
176 self.versionEdit.setText("0.1") |
209 self.versionEdit.setText("0.1") |
177 self.vcsLabel.hide() |
210 self.vcsLabel.hide() |
178 self.vcsInfoButton.hide() |
211 self.vcsInfoButton.hide() |
179 if not self.project.vcsSoftwareAvailable(): |
212 if self.__remoteProject or not self.project.vcsSoftwareAvailable(): |
180 self.vcsCheckBox.hide() |
213 self.vcsCheckBox.hide() |
181 |
214 |
182 self.__origProgrammingLanguage = self.languageComboBox.currentText() |
215 self.__origProgrammingLanguage = self.languageComboBox.currentText() |
183 self.__origMixedFlag = self.mixedLanguageCheckBox.isChecked() |
216 self.__origMixedFlag = self.mixedLanguageCheckBox.isChecked() |
184 self.__origProjectType = self.getProjectType() |
217 self.__origProjectType = self.getProjectType() |
185 |
218 |
|
219 self.__initFileTypesDict(force=True) |
|
220 |
186 self.languageComboBox.currentTextChanged.connect(self.__initFileTypesDict) |
221 self.languageComboBox.currentTextChanged.connect(self.__initFileTypesDict) |
187 self.mixedLanguageCheckBox.stateChanged.connect(self.__initFileTypesDict) |
222 self.mixedLanguageCheckBox.stateChanged.connect(self.__initFileTypesDict) |
188 self.projectTypeComboBox.currentIndexChanged.connect(self.__initFileTypesDict) |
223 self.projectTypeComboBox.currentIndexChanged.connect(self.__initFileTypesDict) |
189 |
224 |
190 self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled( |
225 self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled( |
191 bool(self.dirPicker.text()) |
226 bool(self.dirPicker.text()) |
192 and self.dirPicker.text() not in self.__initPaths |
227 and self.dirPicker.text() not in self.__initPaths |
193 ) |
228 ) |
|
229 |
|
230 def __setMainScriptPickerFilters(self): |
|
231 """ |
|
232 Private method to set the filters for the main script file picker. |
|
233 """ |
|
234 patterns = [] |
|
235 for pattern, filetype in self.__fileTypesDict.items(): |
|
236 if filetype == "SOURCES": |
|
237 patterns.append(pattern) |
|
238 filters = ( |
|
239 self.tr("Source Files ({0});;All Files (*)").format( |
|
240 " ".join(sorted(patterns)) |
|
241 ) |
|
242 if patterns |
|
243 else self.tr("All Files (*)") |
|
244 ) |
|
245 self.mainscriptPicker.setFilters(filters) |
194 |
246 |
195 def __populateLicenseComboBox(self): |
247 def __populateLicenseComboBox(self): |
196 """ |
248 """ |
197 Private method to populate the license selector with the list of trove |
249 Private method to populate the license selector with the list of trove |
198 license types. |
250 license types. |
377 Public method to get the project path. |
454 Public method to get the project path. |
378 |
455 |
379 @return data of the project directory edit |
456 @return data of the project directory edit |
380 @rtype str |
457 @rtype str |
381 """ |
458 """ |
382 return os.path.abspath(self.dirPicker.text()) |
459 if self.__remoteProject: |
383 |
460 return FileSystemUtilities.remoteFileName(self.dirPicker.text()) |
384 @pyqtSlot() |
461 else: |
385 def __initFileTypesDict(self): |
462 return os.path.abspath(self.dirPicker.text()) |
|
463 |
|
464 @pyqtSlot() |
|
465 def __initFileTypesDict(self, force=False): |
386 """ |
466 """ |
387 Private slot to (re-)initialize the filetype dictionary. |
467 Private slot to (re-)initialize the filetype dictionary. |
|
468 |
|
469 @param force flag indicating to force the initialization (defaults to False) |
|
470 @type bool (optional) |
388 """ |
471 """ |
389 if ( |
472 if ( |
390 self.__origProgrammingLanguage != self.languageComboBox.currentText() |
473 force |
|
474 or self.__origProgrammingLanguage != self.languageComboBox.currentText() |
391 or self.__origMixedFlag != self.mixedLanguageCheckBox.isChecked() |
475 or self.__origMixedFlag != self.mixedLanguageCheckBox.isChecked() |
392 or self.__origProjectType != self.getProjectType() |
476 or self.__origProjectType != self.getProjectType() |
393 ): |
477 ): |
394 # any of the defining data got changed |
478 # any of the defining data got changed |
395 self.__fileTypesDict = self.project.defaultFileTypes( |
479 self.__fileTypesDict = self.project.defaultFileTypes( |
426 |
512 |
427 dlg = FiletypeAssociationDialog(self.project, self.__fileTypesDict) |
513 dlg = FiletypeAssociationDialog(self.project, self.__fileTypesDict) |
428 if dlg.exec() == QDialog.DialogCode.Accepted: |
514 if dlg.exec() == QDialog.DialogCode.Accepted: |
429 self.__fileTypesDict = dlg.getData() |
515 self.__fileTypesDict = dlg.getData() |
430 |
516 |
|
517 self.__setMainScriptPickerFilters() |
|
518 |
431 def storeData(self): |
519 def storeData(self): |
432 """ |
520 """ |
433 Public method to store the entered/modified data. |
521 Public method to store the entered/modified data. |
434 """ |
522 """ |
435 self.project.ppath = os.path.abspath(self.dirPicker.text()) |
523 if self.newProject: |
436 fn = self.nameEdit.text() |
524 if self.__remoteProject: |
437 if fn: |
525 self.project.ppath = FileSystemUtilities.remoteFileName( |
438 self.project.name = fn |
526 self.__remotefsInterface.abspath(self.dirPicker.text()) |
439 fn = f"{fn}.epj" |
527 ) |
440 self.project.pfile = os.path.join(self.project.ppath, fn) |
528 fn = self.nameEdit.text() |
441 else: |
529 if fn: |
442 self.project.pfile = "" |
530 self.project.name = fn |
|
531 fn = f"{fn}.epj" |
|
532 self.project.pfile = self.__remotefsInterface.join( |
|
533 self.project.ppath, fn |
|
534 ) |
|
535 else: |
|
536 self.project.pfile = "" |
|
537 else: |
|
538 self.project.ppath = os.path.abspath(self.dirPicker.text()) |
|
539 fn = self.nameEdit.text() |
|
540 if fn: |
|
541 self.project.name = fn |
|
542 fn = f"{fn}.epj" |
|
543 self.project.pfile = os.path.join(self.project.ppath, fn) |
|
544 else: |
|
545 self.project.pfile = "" |
443 self.project.setProjectData(self.versionEdit.text(), dataKey="VERSION") |
546 self.project.setProjectData(self.versionEdit.text(), dataKey="VERSION") |
444 srcDir = self.srcDirPicker.text() |
547 srcDir = self.srcDirPicker.text() |
445 if srcDir: |
548 if srcDir: |
446 srcDir = self.project.getRelativePath(srcDir) |
549 srcDir = self.project.getRelativePath(srcDir) |
447 self.project.setProjectData(srcDir, dataKey="SOURCESDIR") |
550 self.project.setProjectData(srcDir, dataKey="SOURCESDIR") |
449 self.project.setProjectData("", dataKey="SOURCESDIR") |
552 self.project.setProjectData("", dataKey="SOURCESDIR") |
450 fn = self.mainscriptPicker.text() |
553 fn = self.mainscriptPicker.text() |
451 if fn: |
554 if fn: |
452 fn = self.project.getRelativePath(fn) |
555 fn = self.project.getRelativePath(fn) |
453 self.project.setProjectData(fn, dataKey="MAINSCRIPT") |
556 self.project.setProjectData(fn, dataKey="MAINSCRIPT") |
454 self.project.translationsRoot = os.path.splitext(fn)[0] |
557 if self.__remoteProject: |
|
558 self.project.translationsRoot = self.__remotefsInterface.splitext(fn)[0] |
|
559 else: |
|
560 self.project.translationsRoot = os.path.splitext(fn)[0] |
455 else: |
561 else: |
456 self.project.setProjectData("", dataKey="MAINSCRIPT") |
562 self.project.setProjectData("", dataKey="MAINSCRIPT") |
457 self.project.translationsRoot = "" |
563 self.project.translationsRoot = "" |
458 self.project.setProjectData(self.authorEdit.text(), dataKey="AUTHOR") |
564 self.project.setProjectData(self.authorEdit.text(), dataKey="AUTHOR") |
459 self.project.setProjectData(self.emailEdit.text(), dataKey="EMAIL") |
565 self.project.setProjectData(self.emailEdit.text(), dataKey="EMAIL") |