src/eric7/Plugins/WizardPlugins/SetupWizard/SetupWizardDialog.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
16 import tomlkit 16 import tomlkit
17 17
18 import trove_classifiers 18 import trove_classifiers
19 19
20 from PyQt6.QtCore import pyqtSlot, Qt 20 from PyQt6.QtCore import pyqtSlot, Qt
21 from PyQt6.QtWidgets import ( 21 from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QTreeWidgetItem, QListWidgetItem
22 QDialog, QDialogButtonBox, QTreeWidgetItem, QListWidgetItem
23 )
24 22
25 from EricWidgets.EricApplication import ericApp 23 from EricWidgets.EricApplication import ericApp
26 from EricWidgets import EricFileDialog 24 from EricWidgets import EricFileDialog
27 from EricWidgets.EricPathPicker import EricPathPickerModes 25 from EricWidgets.EricPathPicker import EricPathPickerModes
28 26
35 33
36 34
37 class SetupWizardDialog(QDialog, Ui_SetupWizardDialog): 35 class SetupWizardDialog(QDialog, Ui_SetupWizardDialog):
38 """ 36 """
39 Class implementing the setup.py wizard dialog. 37 Class implementing the setup.py wizard dialog.
40 38
41 It displays a dialog for entering the parameters for the setup.py code 39 It displays a dialog for entering the parameters for the setup.py code
42 generator. 40 generator.
43 """ 41 """
42
44 def __init__(self, category, editor, parent=None): 43 def __init__(self, category, editor, parent=None):
45 """ 44 """
46 Constructor 45 Constructor
47 46
48 @param category category of setup file to create 47 @param category category of setup file to create
49 @type str 48 @type str
50 @param editor reference to the editor object to receive the code 49 @param editor reference to the editor object to receive the code
51 @type Editor 50 @type Editor
52 @param parent reference to the parent widget (defaults to None) 51 @param parent reference to the parent widget (defaults to None)
53 @type QWidget (optional) 52 @type QWidget (optional)
54 @exception ValueError raised for an illegal setup file category 53 @exception ValueError raised for an illegal setup file category
55 """ 54 """
56 if category not in ("setup.py", "setup.cfg", "pyproject.toml"): 55 if category not in ("setup.py", "setup.cfg", "pyproject.toml"):
57 raise ValueError("illegal setup file category given") 56 raise ValueError("illegal setup file category given")
58 57
59 super().__init__(parent) 58 super().__init__(parent)
60 self.setupUi(self) 59 self.setupUi(self)
61 60
62 self.setWindowTitle(self.tr("{0} Wizard").format(category)) 61 self.setWindowTitle(self.tr("{0} Wizard").format(category))
63 62
64 self.__replies = [] 63 self.__replies = []
65 self.__category = category 64 self.__category = category
66 self.__editor = editor 65 self.__editor = editor
67 66
68 if category != "setup.py": 67 if category != "setup.py":
69 self.introCheckBox.setVisible(False) 68 self.introCheckBox.setVisible(False)
70 self.importCheckBox.setVisible(False) 69 self.importCheckBox.setVisible(False)
71 self.metaDataCheckBox.setVisible(False) 70 self.metaDataCheckBox.setVisible(False)
72 71
73 self.dataTabWidget.setCurrentIndex(0) 72 self.dataTabWidget.setCurrentIndex(0)
74 73
75 self.packageRootPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) 74 self.packageRootPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
76 self.sourceDirectoryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) 75 self.sourceDirectoryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
77 76
78 self.__mandatoryStyleSheet = ( 77 self.__mandatoryStyleSheet = (
79 "QLineEdit {border: 2px solid; border-color: #dd8888}" 78 "QLineEdit {border: 2px solid; border-color: #dd8888}"
80 if ericApp().usesDarkPalette() else 79 if ericApp().usesDarkPalette()
81 "QLineEdit {border: 2px solid; border-color: #800000}" 80 else "QLineEdit {border: 2px solid; border-color: #800000}"
82 ) 81 )
83 for lineEdit in [self.nameEdit, self.versionEdit, 82 for lineEdit in [
84 self.homePageUrlEdit, self.authorEdit, 83 self.nameEdit,
85 self.authorEmailEdit, self.maintainerEdit, 84 self.versionEdit,
86 self.maintainerEmailEdit]: 85 self.homePageUrlEdit,
86 self.authorEdit,
87 self.authorEmailEdit,
88 self.maintainerEdit,
89 self.maintainerEmailEdit,
90 ]:
87 lineEdit.setStyleSheet(self.__mandatoryStyleSheet) 91 lineEdit.setStyleSheet(self.__mandatoryStyleSheet)
88 92
89 self.__populateClassifiers() 93 self.__populateClassifiers()
90 94
91 self.__okButton = self.buttonBox.button( 95 self.__okButton = self.buttonBox.button(QDialogButtonBox.StandardButton.Ok)
92 QDialogButtonBox.StandardButton.Ok)
93 self.__okButton.setEnabled(False) 96 self.__okButton.setEnabled(False)
94 97
95 projectOpen = ericApp().getObject("Project").isOpen() 98 projectOpen = ericApp().getObject("Project").isOpen()
96 self.projectButton.setEnabled(projectOpen) 99 self.projectButton.setEnabled(projectOpen)
97 100
98 self.projectUrlsList.header().setSortIndicator(0, Qt.SortOrder.AscendingOrder) 101 self.projectUrlsList.header().setSortIndicator(0, Qt.SortOrder.AscendingOrder)
99 self.entryPointsList.header().setSortIndicator(0, Qt.SortOrder.AscendingOrder) 102 self.entryPointsList.header().setSortIndicator(0, Qt.SortOrder.AscendingOrder)
100 103
101 self.descriptionContentTypeComboBox.addItem("", "") 104 self.descriptionContentTypeComboBox.addItem("", "")
102 for contentType, mimetype in sorted([ 105 for contentType, mimetype in sorted(
103 (self.tr("Plain Text"), "text/plain"), 106 [
104 (self.tr("Markdown"), "text/markdown"), 107 (self.tr("Plain Text"), "text/plain"),
105 (self.tr("reStructuredText"), "text/x-rst") 108 (self.tr("Markdown"), "text/markdown"),
106 109 (self.tr("reStructuredText"), "text/x-rst"),
107 ]): 110 ]
111 ):
108 self.descriptionContentTypeComboBox.addItem(contentType, mimetype) 112 self.descriptionContentTypeComboBox.addItem(contentType, mimetype)
109 113
110 self.homePageUrlEdit.textChanged.connect(self.__enableOkButton) 114 self.homePageUrlEdit.textChanged.connect(self.__enableOkButton)
111 self.nameEdit.textChanged.connect(self.__enableOkButton) 115 self.nameEdit.textChanged.connect(self.__enableOkButton)
112 self.versionEdit.textChanged.connect(self.__enableOkButton) 116 self.versionEdit.textChanged.connect(self.__enableOkButton)
113 self.authorEdit.textChanged.connect(self.__enableOkButton) 117 self.authorEdit.textChanged.connect(self.__enableOkButton)
114 self.authorEmailEdit.textChanged.connect(self.__enableOkButton) 118 self.authorEmailEdit.textChanged.connect(self.__enableOkButton)
115 self.maintainerEdit.textChanged.connect(self.__enableOkButton) 119 self.maintainerEdit.textChanged.connect(self.__enableOkButton)
116 self.maintainerEmailEdit.textChanged.connect(self.__enableOkButton) 120 self.maintainerEmailEdit.textChanged.connect(self.__enableOkButton)
117 121
118 def __enableOkButton(self): 122 def __enableOkButton(self):
119 """ 123 """
120 Private slot to set the state of the OK button. 124 Private slot to set the state of the OK button.
121 """ 125 """
122 enable = ( 126 enable = (
123 bool(self.nameEdit.text()) and 127 bool(self.nameEdit.text())
124 bool(self.versionEdit.text()) and 128 and bool(self.versionEdit.text())
125 bool(self.homePageUrlEdit.text()) and 129 and bool(self.homePageUrlEdit.text())
126 ((bool(self.authorEdit.text()) and 130 and (
127 bool(self.authorEmailEdit.text())) or 131 (bool(self.authorEdit.text()) and bool(self.authorEmailEdit.text()))
128 (bool(self.maintainerEdit.text()) and 132 or (
129 bool(self.maintainerEmailEdit.text()))) and 133 bool(self.maintainerEdit.text())
130 self.homePageUrlEdit.text().startswith(("http://", "https://")) 134 and bool(self.maintainerEmailEdit.text())
131 ) 135 )
132 136 )
137 and self.homePageUrlEdit.text().startswith(("http://", "https://"))
138 )
139
133 self.__okButton.setEnabled(enable) 140 self.__okButton.setEnabled(enable)
134 141
135 def __populateClassifiers(self): 142 def __populateClassifiers(self):
136 """ 143 """
137 Private method to populate the classifiers. 144 Private method to populate the classifiers.
138 """ 145 """
139 self.licenseClassifierComboBox.clear() 146 self.licenseClassifierComboBox.clear()
140 self.classifiersList.clear() 147 self.classifiersList.clear()
141 self.developmentStatusComboBox.clear() 148 self.developmentStatusComboBox.clear()
142 149
143 self.developmentStatusComboBox.addItem("", "") 150 self.developmentStatusComboBox.addItem("", "")
144 151
145 self.__classifiersDict = {} 152 self.__classifiersDict = {}
146 for classifier in trove_classifiers.sorted_classifiers: 153 for classifier in trove_classifiers.sorted_classifiers:
147 if classifier.startswith("License ::"): 154 if classifier.startswith("License ::"):
148 self.licenseClassifierComboBox.addItem( 155 self.licenseClassifierComboBox.addItem(
149 "/".join(classifier.split(" :: ")[1:]), 156 "/".join(classifier.split(" :: ")[1:]), classifier
150 classifier
151 ) 157 )
152 elif classifier.startswith("Development Status ::"): 158 elif classifier.startswith("Development Status ::"):
153 self.developmentStatusComboBox.addItem( 159 self.developmentStatusComboBox.addItem(
154 classifier.split(" :: ")[1], classifier) 160 classifier.split(" :: ")[1], classifier
161 )
155 else: 162 else:
156 self.__addClassifierEntry(classifier) 163 self.__addClassifierEntry(classifier)
157 self.__classifiersDict = {} 164 self.__classifiersDict = {}
158 165
159 self.licenseClassifierComboBox.setCurrentIndex( 166 self.licenseClassifierComboBox.setCurrentIndex(
160 self.licenseClassifierComboBox.findText( 167 self.licenseClassifierComboBox.findText(
161 "(GPLv3)", 168 "(GPLv3)", Qt.MatchFlag.MatchContains | Qt.MatchFlag.MatchCaseSensitive
162 Qt.MatchFlag.MatchContains | Qt.MatchFlag.MatchCaseSensitive 169 )
163 ) 170 )
164 ) 171
165
166 def __addClassifierEntry(self, classifier): 172 def __addClassifierEntry(self, classifier):
167 """ 173 """
168 Private method to add a new entry to the list of trove classifiers. 174 Private method to add a new entry to the list of trove classifiers.
169 175
170 @param classifier classifier containing the data for the entry 176 @param classifier classifier containing the data for the entry
171 @type str 177 @type str
172 """ 178 """
173 itm = None 179 itm = None
174 pitm = None 180 pitm = None
175 dataList = classifier.split(" :: ") 181 dataList = classifier.split(" :: ")
176 for index in range(len(dataList)): 182 for index in range(len(dataList)):
177 key = " :: ".join(dataList[:index + 1]) 183 key = " :: ".join(dataList[: index + 1])
178 if key not in self.__classifiersDict: 184 if key not in self.__classifiersDict:
179 if pitm is None: 185 if pitm is None:
180 itm = QTreeWidgetItem( 186 itm = QTreeWidgetItem(self.classifiersList, [dataList[index]])
181 self.classifiersList, [dataList[index]])
182 pitm = itm 187 pitm = itm
183 else: 188 else:
184 itm = QTreeWidgetItem(pitm, [dataList[index]]) 189 itm = QTreeWidgetItem(pitm, [dataList[index]])
185 itm.setExpanded(True) 190 itm.setExpanded(True)
186 self.__classifiersDict[key] = itm 191 self.__classifiersDict[key] = itm
187 else: 192 else:
188 pitm = self.__classifiersDict[key] 193 pitm = self.__classifiersDict[key]
189 itm.setCheckState(0, Qt.CheckState.Unchecked) 194 itm.setCheckState(0, Qt.CheckState.Unchecked)
190 itm.setData(0, Qt.ItemDataRole.UserRole, classifier) 195 itm.setData(0, Qt.ItemDataRole.UserRole, classifier)
191 196
192 def __getLicenseText(self): 197 def __getLicenseText(self):
193 """ 198 """
194 Private method to get the license text. 199 Private method to get the license text.
195 200
196 @return license text 201 @return license text
197 @rtype str 202 @rtype str
198 """ 203 """
199 if not self.licenseClassifierCheckBox.isChecked(): 204 if not self.licenseClassifierCheckBox.isChecked():
200 return self.licenseEdit.text() 205 return self.licenseEdit.text()
201 else: 206 else:
202 lic = self.licenseClassifierComboBox.currentText() 207 lic = self.licenseClassifierComboBox.currentText()
203 if "(" in lic: 208 if "(" in lic:
204 lic = lic.rsplit("(", 1)[1].split(")", 1)[0] 209 lic = lic.rsplit("(", 1)[1].split(")", 1)[0]
205 return lic 210 return lic
206 211
207 def __getSetupPyCode(self, indLevel, indString): 212 def __getSetupPyCode(self, indLevel, indString):
208 """ 213 """
209 Private method to get the source code for a 'setup.py' file. 214 Private method to get the source code for a 'setup.py' file.
210 215
211 @param indLevel indentation level 216 @param indLevel indentation level
212 @type int 217 @type int
213 @param indString string used for indentation (space or tab) 218 @param indString string used for indentation (space or tab)
214 @type str 219 @type str
215 @return generated code 220 @return generated code
216 @rtype str 221 @rtype str
217 """ 222 """
218 # Note: all paths are created with '/'; setup will do the right thing 223 # Note: all paths are created with '/'; setup will do the right thing
219 224
220 # calculate our indentation level and the indentation string 225 # calculate our indentation level and the indentation string
221 il = indLevel + 1 226 il = indLevel + 1
222 istring = il * indString 227 istring = il * indString
223 i1string = (il + 1) * indString 228 i1string = (il + 1) * indString
224 i2string = (il + 2) * indString 229 i2string = (il + 2) * indString
225 estring = os.linesep + indLevel * indString 230 estring = os.linesep + indLevel * indString
226 231
227 # now generate the code 232 # now generate the code
228 if self.introCheckBox.isChecked(): 233 if self.introCheckBox.isChecked():
229 sourceCode = "#!/usr/bin/env python3{0}".format(os.linesep) 234 sourceCode = "#!/usr/bin/env python3{0}".format(os.linesep)
230 sourceCode += "# -*- coding: utf-8 -*-{0}{0}".format(os.linesep) 235 sourceCode += "# -*- coding: utf-8 -*-{0}{0}".format(os.linesep)
231 else: 236 else:
232 sourceCode = "" 237 sourceCode = ""
233 238
234 if self.metaDataCheckBox.isChecked(): 239 if self.metaDataCheckBox.isChecked():
235 sourceCode += '# metadata{0}'.format(os.linesep) 240 sourceCode += "# metadata{0}".format(os.linesep)
236 sourceCode += '"{0}"{1}'.format( 241 sourceCode += '"{0}"{1}'.format(
237 self.summaryEdit.text() or "Setup routine", 242 self.summaryEdit.text() or "Setup routine", os.linesep
238 os.linesep
239 ) 243 )
240 sourceCode += '__version__ = "{0}"{1}'.format( 244 sourceCode += '__version__ = "{0}"{1}'.format(
241 self.versionEdit.text(), os.linesep) 245 self.versionEdit.text(), os.linesep
246 )
242 sourceCode += '__license__ = "{0}"{1}'.format( 247 sourceCode += '__license__ = "{0}"{1}'.format(
243 self.__getLicenseText(), os.linesep) 248 self.__getLicenseText(), os.linesep
249 )
244 sourceCode += '__author__ = "{0}"{1}'.format( 250 sourceCode += '__author__ = "{0}"{1}'.format(
245 self.authorEdit.text() or self.maintainerEdit.text(), 251 self.authorEdit.text() or self.maintainerEdit.text(), os.linesep
246 os.linesep) 252 )
247 sourceCode += '__email__ = "{0}"{1}'.format( 253 sourceCode += '__email__ = "{0}"{1}'.format(
248 self.authorEmailEdit.text() or self.maintainerEmailEdit.text(), 254 self.authorEmailEdit.text() or self.maintainerEmailEdit.text(),
249 os.linesep) 255 os.linesep,
256 )
250 sourceCode += '__url__ = "{0}"{1}'.format( 257 sourceCode += '__url__ = "{0}"{1}'.format(
251 self.homePageUrlEdit.text(), os.linesep) 258 self.homePageUrlEdit.text(), os.linesep
259 )
252 sourceCode += '__date__ = "{0}"{1}'.format( 260 sourceCode += '__date__ = "{0}"{1}'.format(
253 datetime.datetime.now().isoformat().split('.')[0], os.linesep) 261 datetime.datetime.now().isoformat().split(".")[0], os.linesep
254 sourceCode += '__prj__ = "{0}"{1}'.format( 262 )
255 self.nameEdit.text(), os.linesep) 263 sourceCode += '__prj__ = "{0}"{1}'.format(self.nameEdit.text(), os.linesep)
256 sourceCode += os.linesep 264 sourceCode += os.linesep
257 265
258 if self.importCheckBox.isChecked(): 266 if self.importCheckBox.isChecked():
259 additionalImport = ", find_packages" 267 additionalImport = ", find_packages"
260 sourceCode += "from setuptools import setup{0}{1}".format( 268 sourceCode += "from setuptools import setup{0}{1}".format(
261 additionalImport, os.linesep) 269 additionalImport, os.linesep
270 )
262 if sourceCode: 271 if sourceCode:
263 sourceCode += "{0}{0}".format(os.linesep) 272 sourceCode += "{0}{0}".format(os.linesep)
264 273
265 if self.descriptionFromFilesCheckBox.isChecked(): 274 if self.descriptionFromFilesCheckBox.isChecked():
266 sourceCode += 'def get_long_description():{0}'.format(os.linesep) 275 sourceCode += "def get_long_description():{0}".format(os.linesep)
267 sourceCode += '{0}descr = []{1}'.format(istring, os.linesep) 276 sourceCode += "{0}descr = []{1}".format(istring, os.linesep)
268 sourceCode += '{0}for fname in ("{1}"):{2}'.format( 277 sourceCode += '{0}for fname in ("{1}"):{2}'.format(
269 istring, 278 istring,
270 '", "'.join(self.descriptionEdit.toPlainText().splitlines()), 279 '", "'.join(self.descriptionEdit.toPlainText().splitlines()),
271 os.linesep) 280 os.linesep,
281 )
272 sourceCode += ( 282 sourceCode += (
273 '{0}with open(fname, "r", encoding="utf-8") as f:{1}' 283 '{0}with open(fname, "r", encoding="utf-8") as f:{1}'
274 ).format(i1string, os.linesep) 284 ).format(i1string, os.linesep)
275 sourceCode += '{0}descr.append(f.read()){1}'.format( 285 sourceCode += "{0}descr.append(f.read()){1}".format(i2string, os.linesep)
276 i2string, os.linesep)
277 sourceCode += '{0}return "\\n\\n".join(descr){1}'.format( 286 sourceCode += '{0}return "\\n\\n".join(descr){1}'.format(
278 istring, os.linesep) 287 istring, os.linesep
288 )
279 sourceCode += "{0}{0}".format(os.linesep) 289 sourceCode += "{0}{0}".format(os.linesep)
280 290
281 sourceCode += 'setup({0}'.format(os.linesep) 291 sourceCode += "setup({0}".format(os.linesep)
282 sourceCode += '{0}name="{1}",{2}'.format( 292 sourceCode += '{0}name="{1}",{2}'.format(
283 istring, self.nameEdit.text(), os.linesep) 293 istring, self.nameEdit.text(), os.linesep
294 )
284 sourceCode += '{0}version="{1}",{2}'.format( 295 sourceCode += '{0}version="{1}",{2}'.format(
285 istring, self.versionEdit.text(), os.linesep) 296 istring, self.versionEdit.text(), os.linesep
286 297 )
298
287 if self.summaryEdit.text(): 299 if self.summaryEdit.text():
288 sourceCode += '{0}description="{1}",{2}'.format( 300 sourceCode += '{0}description="{1}",{2}'.format(
289 istring, self.summaryEdit.text(), os.linesep) 301 istring, self.summaryEdit.text(), os.linesep
290 302 )
303
291 if self.descriptionFromFilesCheckBox.isChecked(): 304 if self.descriptionFromFilesCheckBox.isChecked():
292 sourceCode += '{0}long_description=get_long_description(),{1}'.format( 305 sourceCode += "{0}long_description=get_long_description(),{1}".format(
293 istring, os.linesep) 306 istring, os.linesep
307 )
294 elif self.descriptionEdit.toPlainText(): 308 elif self.descriptionEdit.toPlainText():
295 sourceCode += '{0}long_description="""{1}""",{2}'.format( 309 sourceCode += '{0}long_description="""{1}""",{2}'.format(
296 istring, self.descriptionEdit.toPlainText(), os.linesep) 310 istring, self.descriptionEdit.toPlainText(), os.linesep
297 311 )
312
298 if self.descriptionContentTypeComboBox.currentData(): 313 if self.descriptionContentTypeComboBox.currentData():
299 sourceCode += '{0}long_description_content_type="{1}",{2}'.format( 314 sourceCode += '{0}long_description_content_type="{1}",{2}'.format(
300 istring, self.descriptionContentTypeComboBox.currentData(), os.linesep) 315 istring, self.descriptionContentTypeComboBox.currentData(), os.linesep
301 316 )
317
302 if self.authorEdit.text(): 318 if self.authorEdit.text():
303 sourceCode += '{0}author="{1}",{2}'.format( 319 sourceCode += '{0}author="{1}",{2}'.format(
304 istring, self.authorEdit.text(), os.linesep) 320 istring, self.authorEdit.text(), os.linesep
321 )
305 sourceCode += '{0}author_email="{1}",{2}'.format( 322 sourceCode += '{0}author_email="{1}",{2}'.format(
306 istring, self.authorEmailEdit.text(), os.linesep) 323 istring, self.authorEmailEdit.text(), os.linesep
307 324 )
325
308 if self.maintainerEdit.text(): 326 if self.maintainerEdit.text():
309 sourceCode += '{0}maintainer="{1}",{2}'.format( 327 sourceCode += '{0}maintainer="{1}",{2}'.format(
310 istring, self.maintainerEdit.text(), os.linesep) 328 istring, self.maintainerEdit.text(), os.linesep
329 )
311 sourceCode += '{0}maintainer_email="{1}",{2}'.format( 330 sourceCode += '{0}maintainer_email="{1}",{2}'.format(
312 istring, self.maintainerEmailEdit.text(), os.linesep) 331 istring, self.maintainerEmailEdit.text(), os.linesep
313 332 )
333
314 sourceCode += '{0}url="{1}",{2}'.format( 334 sourceCode += '{0}url="{1}",{2}'.format(
315 istring, self.homePageUrlEdit.text(), os.linesep) 335 istring, self.homePageUrlEdit.text(), os.linesep
336 )
316 if self.downloadUrlEdit.text(): 337 if self.downloadUrlEdit.text():
317 sourceCode += '{0}download_url="{1}",{2}'.format( 338 sourceCode += '{0}download_url="{1}",{2}'.format(
318 istring, self.downloadUrlEdit.text(), os.linesep) 339 istring, self.downloadUrlEdit.text(), os.linesep
319 340 )
341
320 if self.projectUrlsList.topLevelItemCount(): 342 if self.projectUrlsList.topLevelItemCount():
321 sourceCode += '{0}project_urls={{{1}'.format(istring, os.linesep) 343 sourceCode += "{0}project_urls={{{1}".format(istring, os.linesep)
322 for row in range(self.projectUrlsList.topLevelItemCount()): 344 for row in range(self.projectUrlsList.topLevelItemCount()):
323 urlItem = self.projectUrlsList.topLevelItem(row) 345 urlItem = self.projectUrlsList.topLevelItem(row)
324 sourceCode += '{0}"{1}": "{2}",{3}'.format( 346 sourceCode += '{0}"{1}": "{2}",{3}'.format(
325 i1string, urlItem.text(0), urlItem.text(1), os.linesep) 347 i1string, urlItem.text(0), urlItem.text(1), os.linesep
326 sourceCode += '{0}}},{1}'.format(istring, os.linesep) 348 )
327 349 sourceCode += "{0}}},{1}".format(istring, os.linesep)
350
328 classifiers = [] 351 classifiers = []
329 if not self.licenseClassifierCheckBox.isChecked(): 352 if not self.licenseClassifierCheckBox.isChecked():
330 sourceCode += '{0}license="{1}",{2}'.format( 353 sourceCode += '{0}license="{1}",{2}'.format(
331 istring, self.licenseEdit.text(), os.linesep) 354 istring, self.licenseEdit.text(), os.linesep
355 )
332 else: 356 else:
333 classifiers.append( 357 classifiers.append(
334 self.licenseClassifierComboBox.itemData( 358 self.licenseClassifierComboBox.itemData(
335 self.licenseClassifierComboBox.currentIndex())) 359 self.licenseClassifierComboBox.currentIndex()
336 360 )
361 )
362
337 platforms = self.platformsEdit.toPlainText().splitlines() 363 platforms = self.platformsEdit.toPlainText().splitlines()
338 if platforms: 364 if platforms:
339 sourceCode += '{0}platforms=[{1}'.format(istring, os.linesep) 365 sourceCode += "{0}platforms=[{1}".format(istring, os.linesep)
340 sourceCode += '{0}"{1}"{2}'.format( 366 sourceCode += '{0}"{1}"{2}'.format(
341 i1string, 367 i1string,
342 '",{0}{1}"'.format(os.linesep, i1string).join(platforms), 368 '",{0}{1}"'.format(os.linesep, i1string).join(platforms),
343 os.linesep) 369 os.linesep,
344 sourceCode += '{0}],{1}'.format(istring, os.linesep) 370 )
345 371 sourceCode += "{0}],{1}".format(istring, os.linesep)
372
346 if self.developmentStatusComboBox.currentIndex() != 0: 373 if self.developmentStatusComboBox.currentIndex() != 0:
347 classifiers.append(self.developmentStatusComboBox.currentData()) 374 classifiers.append(self.developmentStatusComboBox.currentData())
348 375
349 itm = self.classifiersList.topLevelItem(0) 376 itm = self.classifiersList.topLevelItem(0)
350 while itm: 377 while itm:
351 itm.setExpanded(True) 378 itm.setExpanded(True)
352 if itm.checkState(0) == Qt.CheckState.Checked: 379 if itm.checkState(0) == Qt.CheckState.Checked:
353 classifiers.append(itm.data(0, Qt.ItemDataRole.UserRole)) 380 classifiers.append(itm.data(0, Qt.ItemDataRole.UserRole))
354 itm = self.classifiersList.itemBelow(itm) 381 itm = self.classifiersList.itemBelow(itm)
355 382
356 # cleanup classifiers list - remove all invalid entries 383 # cleanup classifiers list - remove all invalid entries
357 classifiers = [c for c in classifiers if bool(c)] 384 classifiers = [c for c in classifiers if bool(c)]
358 if classifiers: 385 if classifiers:
359 sourceCode += '{0}classifiers=[{1}'.format(istring, os.linesep) 386 sourceCode += "{0}classifiers=[{1}".format(istring, os.linesep)
360 sourceCode += '{0}"{1}"{2}'.format( 387 sourceCode += '{0}"{1}"{2}'.format(
361 i1string, 388 i1string,
362 '",{0}{1}"'.format(os.linesep, i1string).join(classifiers), 389 '",{0}{1}"'.format(os.linesep, i1string).join(classifiers),
363 os.linesep) 390 os.linesep,
364 sourceCode += '{0}],{1}'.format(istring, os.linesep) 391 )
392 sourceCode += "{0}],{1}".format(istring, os.linesep)
365 del classifiers 393 del classifiers
366 394
367 if self.keywordsEdit.text(): 395 if self.keywordsEdit.text():
368 sourceCode += '{0}keywords="{1}",{2}'.format( 396 sourceCode += '{0}keywords="{1}",{2}'.format(
369 istring, self.keywordsEdit.text(), os.linesep) 397 istring, self.keywordsEdit.text(), os.linesep
370 398 )
399
371 if self.pyVersionEdit.text(): 400 if self.pyVersionEdit.text():
372 sourceCode += '{0}python_requires="{1}",{2}'.format( 401 sourceCode += '{0}python_requires="{1}",{2}'.format(
373 istring, self.pyVersionEdit.text(), os.linesep) 402 istring, self.pyVersionEdit.text(), os.linesep
374 403 )
375 sourceCode += '{0}packages=find_packages('.format(istring) 404
376 src = Utilities.fromNativeSeparators( 405 sourceCode += "{0}packages=find_packages(".format(istring)
377 self.sourceDirectoryPicker.text()) 406 src = Utilities.fromNativeSeparators(self.sourceDirectoryPicker.text())
378 excludePatterns = [] 407 excludePatterns = []
379 for row in range(self.excludePatternList.count()): 408 for row in range(self.excludePatternList.count()):
380 excludePatterns.append( 409 excludePatterns.append(self.excludePatternList.item(row).text())
381 self.excludePatternList.item(row).text())
382 if src: 410 if src:
383 sourceCode += '{0}{1}"{2}"'.format(os.linesep, i1string, src) 411 sourceCode += '{0}{1}"{2}"'.format(os.linesep, i1string, src)
384 if excludePatterns: 412 if excludePatterns:
385 sourceCode += ',' 413 sourceCode += ","
386 else: 414 else:
387 sourceCode += '{0}{1}'.format(os.linesep, istring) 415 sourceCode += "{0}{1}".format(os.linesep, istring)
388 if excludePatterns: 416 if excludePatterns:
389 sourceCode += '{0}{1}exclude=[{0}'.format(os.linesep, i1string) 417 sourceCode += "{0}{1}exclude=[{0}".format(os.linesep, i1string)
390 sourceCode += '{0}"{1}"{2}'.format( 418 sourceCode += '{0}"{1}"{2}'.format(
391 i2string, 419 i2string,
392 '",{0}{1}"'.format(os.linesep, i2string) 420 '",{0}{1}"'.format(os.linesep, i2string).join(excludePatterns),
393 .join(excludePatterns), 421 os.linesep,
394 os.linesep) 422 )
395 sourceCode += '{0}]{1}{2}'.format(i1string, os.linesep, istring) 423 sourceCode += "{0}]{1}{2}".format(i1string, os.linesep, istring)
396 sourceCode += '),{0}'.format(os.linesep) 424 sourceCode += "),{0}".format(os.linesep)
397 425
398 if self.includePackageDataCheckBox.isChecked(): 426 if self.includePackageDataCheckBox.isChecked():
399 sourceCode += '{0}include_package_data = True,{1}'.format( 427 sourceCode += "{0}include_package_data = True,{1}".format(
400 istring, os.linesep) 428 istring, os.linesep
401 429 )
430
402 modules = [] 431 modules = []
403 for row in range(self.modulesList.count()): 432 for row in range(self.modulesList.count()):
404 modules.append(self.modulesList.item(row).text()) 433 modules.append(self.modulesList.item(row).text())
405 if modules: 434 if modules:
406 sourceCode += '{0}py_modules=[{1}'.format(istring, os.linesep) 435 sourceCode += "{0}py_modules=[{1}".format(istring, os.linesep)
407 sourceCode += '{0}"{1}"{2}'.format( 436 sourceCode += '{0}"{1}"{2}'.format(
408 i1string, 437 i1string,
409 '",{0}{1}"'.format(os.linesep, i1string).join(modules), 438 '",{0}{1}"'.format(os.linesep, i1string).join(modules),
410 os.linesep) 439 os.linesep,
411 sourceCode += '{0}],{1}'.format(istring, os.linesep) 440 )
441 sourceCode += "{0}],{1}".format(istring, os.linesep)
412 del modules 442 del modules
413 443
414 if self.entryPointsList.topLevelItemCount(): 444 if self.entryPointsList.topLevelItemCount():
415 entryPoints = { 445 entryPoints = {
416 "console_scripts": [], 446 "console_scripts": [],
417 "gui_scripts": [], 447 "gui_scripts": [],
418 } 448 }
419 for row in range(self.entryPointsList.topLevelItemCount()): 449 for row in range(self.entryPointsList.topLevelItemCount()):
420 itm = self.entryPointsList.topLevelItem(row) 450 itm = self.entryPointsList.topLevelItem(row)
421 entryPoints[itm.data(0, Qt.ItemDataRole.UserRole)].append( 451 entryPoints[itm.data(0, Qt.ItemDataRole.UserRole)].append(
422 "{0} = {1}".format(itm.text(1), itm.text(2)) 452 "{0} = {1}".format(itm.text(1), itm.text(2))
423 ) 453 )
424 sourceCode += '{0}entry_points={{{1}'.format(istring, os.linesep) 454 sourceCode += "{0}entry_points={{{1}".format(istring, os.linesep)
425 for epCategory in entryPoints: 455 for epCategory in entryPoints:
426 if entryPoints[epCategory]: 456 if entryPoints[epCategory]:
427 sourceCode += '{0}"{1}": [{2}'.format( 457 sourceCode += '{0}"{1}": [{2}'.format(
428 i1string, epCategory, os.linesep) 458 i1string, epCategory, os.linesep
459 )
429 for entryPoint in entryPoints[epCategory]: 460 for entryPoint in entryPoints[epCategory]:
430 sourceCode += '{0}"{1}",{2}'.format( 461 sourceCode += '{0}"{1}",{2}'.format(
431 i2string, entryPoint, os.linesep) 462 i2string, entryPoint, os.linesep
432 sourceCode += '{0}],{1}'.format(i1string, os.linesep) 463 )
433 sourceCode += '{0}}},{1}'.format(istring, os.linesep) 464 sourceCode += "{0}],{1}".format(i1string, os.linesep)
434 465 sourceCode += "{0}}},{1}".format(istring, os.linesep)
466
435 sourceCode += "){0}".format(estring) 467 sourceCode += "){0}".format(estring)
436 return sourceCode 468 return sourceCode
437 469
438 def __getSetupCfgCode(self): 470 def __getSetupCfgCode(self):
439 """ 471 """
440 Private method to get the source code for a 'setup.cfg' file. 472 Private method to get the source code for a 'setup.cfg' file.
441 473
442 @return generated code 474 @return generated code
443 @rtype str 475 @rtype str
444 """ 476 """
445 from . import SetupCfgUtilities 477 from . import SetupCfgUtilities
478
446 metadata = { 479 metadata = {
447 "name": self.nameEdit.text(), 480 "name": self.nameEdit.text(),
448 "version": self.versionEdit.text(), 481 "version": self.versionEdit.text(),
449 } 482 }
450 483
451 if self.summaryEdit.text(): 484 if self.summaryEdit.text():
452 metadata["description"] = self.summaryEdit.text() 485 metadata["description"] = self.summaryEdit.text()
453 486
454 if self.descriptionEdit.toPlainText(): 487 if self.descriptionEdit.toPlainText():
455 metadata["long_description"] = ( 488 metadata["long_description"] = (
456 "file: {0}".format( 489 "file: {0}".format(
457 ", ".join(self.descriptionEdit.toPlainText().splitlines()) 490 ", ".join(self.descriptionEdit.toPlainText().splitlines())
458 ) 491 )
459 if self.descriptionFromFilesCheckBox.isChecked() else 492 if self.descriptionFromFilesCheckBox.isChecked()
460 self.descriptionEdit.toPlainText() 493 else self.descriptionEdit.toPlainText()
461 ) 494 )
462 495
463 if self.descriptionContentTypeComboBox.currentData(): 496 if self.descriptionContentTypeComboBox.currentData():
464 metadata["long_description_content_type"] = ( 497 metadata[
465 self.descriptionContentTypeComboBox.currentData() 498 "long_description_content_type"
466 ) 499 ] = self.descriptionContentTypeComboBox.currentData()
467 500
468 if self.authorEdit.text(): 501 if self.authorEdit.text():
469 metadata["author"] = self.authorEdit.text() 502 metadata["author"] = self.authorEdit.text()
470 metadata["author_email"] = self.authorEmailEdit.text() 503 metadata["author_email"] = self.authorEmailEdit.text()
471 504
472 if self.maintainerEdit.text(): 505 if self.maintainerEdit.text():
473 metadata["maintainer"] = self.maintainerEdit.text() 506 metadata["maintainer"] = self.maintainerEdit.text()
474 metadata["maintainer_email"] = self.maintainerEmailEdit.text() 507 metadata["maintainer_email"] = self.maintainerEmailEdit.text()
475 508
476 metadata["url"] = self.homePageUrlEdit.text() 509 metadata["url"] = self.homePageUrlEdit.text()
477 if self.downloadUrlEdit.text(): 510 if self.downloadUrlEdit.text():
478 metadata["download_url"] = self.downloadUrlEdit.text() 511 metadata["download_url"] = self.downloadUrlEdit.text()
479 512
480 if self.projectUrlsList.topLevelItemCount(): 513 if self.projectUrlsList.topLevelItemCount():
481 projectURLs = {} 514 projectURLs = {}
482 for row in range(self.projectUrlsList.topLevelItemCount()): 515 for row in range(self.projectUrlsList.topLevelItemCount()):
483 urlItem = self.projectUrlsList.topLevelItem(row) 516 urlItem = self.projectUrlsList.topLevelItem(row)
484 projectURLs[urlItem.text(0)] = urlItem.text(1) 517 projectURLs[urlItem.text(0)] = urlItem.text(1)
485 metadata["project_urls"] = SetupCfgUtilities.toString(projectURLs) 518 metadata["project_urls"] = SetupCfgUtilities.toString(projectURLs)
486 519
487 classifiers = [] 520 classifiers = []
488 if not self.licenseClassifierCheckBox.isChecked(): 521 if not self.licenseClassifierCheckBox.isChecked():
489 metadata["license"] = self.licenseEdit.text() 522 metadata["license"] = self.licenseEdit.text()
490 else: 523 else:
491 classifiers.append( 524 classifiers.append(
492 self.licenseClassifierComboBox.itemData( 525 self.licenseClassifierComboBox.itemData(
493 self.licenseClassifierComboBox.currentIndex())) 526 self.licenseClassifierComboBox.currentIndex()
494 527 )
528 )
529
495 platforms = self.platformsEdit.toPlainText().splitlines() 530 platforms = self.platformsEdit.toPlainText().splitlines()
496 if platforms: 531 if platforms:
497 metadata["platforms"] = SetupCfgUtilities.toString(platforms) 532 metadata["platforms"] = SetupCfgUtilities.toString(platforms)
498 533
499 if self.developmentStatusComboBox.currentIndex() != 0: 534 if self.developmentStatusComboBox.currentIndex() != 0:
500 classifiers.append(self.developmentStatusComboBox.currentData()) 535 classifiers.append(self.developmentStatusComboBox.currentData())
501 536
502 itm = self.classifiersList.topLevelItem(0) 537 itm = self.classifiersList.topLevelItem(0)
503 while itm: 538 while itm:
504 itm.setExpanded(True) 539 itm.setExpanded(True)
505 if itm.checkState(0) == Qt.CheckState.Checked: 540 if itm.checkState(0) == Qt.CheckState.Checked:
506 classifiers.append(itm.data(0, Qt.ItemDataRole.UserRole)) 541 classifiers.append(itm.data(0, Qt.ItemDataRole.UserRole))
507 itm = self.classifiersList.itemBelow(itm) 542 itm = self.classifiersList.itemBelow(itm)
508 543
509 # cleanup classifiers list - remove all invalid entries 544 # cleanup classifiers list - remove all invalid entries
510 classifiers = [c for c in classifiers if bool(c)] 545 classifiers = [c for c in classifiers if bool(c)]
511 if classifiers: 546 if classifiers:
512 metadata["classifiers"] = SetupCfgUtilities.toString(classifiers) 547 metadata["classifiers"] = SetupCfgUtilities.toString(classifiers)
513 548
514 if self.keywordsEdit.text(): 549 if self.keywordsEdit.text():
515 metadata["keywords"] = SetupCfgUtilities.toString( 550 metadata["keywords"] = SetupCfgUtilities.toString(
516 self.keywordsEdit.text().split()) 551 self.keywordsEdit.text().split()
517 552 )
518 options = { 553
519 "packages": "find:" 554 options = {"packages": "find:"}
520 } 555
521
522 if self.pyVersionEdit.text(): 556 if self.pyVersionEdit.text():
523 options["python_requires"] = self.pyVersionEdit.text() 557 options["python_requires"] = self.pyVersionEdit.text()
524 558
525 findOptions = {} 559 findOptions = {}
526 src = Utilities.fromNativeSeparators(self.sourceDirectoryPicker.text()) 560 src = Utilities.fromNativeSeparators(self.sourceDirectoryPicker.text())
527 excludePatterns = [] 561 excludePatterns = []
528 for row in range(self.excludePatternList.count()): 562 for row in range(self.excludePatternList.count()):
529 excludePatterns.append( 563 excludePatterns.append(self.excludePatternList.item(row).text())
530 self.excludePatternList.item(row).text())
531 if src: 564 if src:
532 options["package_dir"] = SetupCfgUtilities.toString({"": src}) 565 options["package_dir"] = SetupCfgUtilities.toString({"": src})
533 findOptions["where"] = src 566 findOptions["where"] = src
534 if excludePatterns: 567 if excludePatterns:
535 findOptions["exclude"] = SetupCfgUtilities.toString(excludePatterns) 568 findOptions["exclude"] = SetupCfgUtilities.toString(excludePatterns)
536 569
537 if self.includePackageDataCheckBox.isChecked(): 570 if self.includePackageDataCheckBox.isChecked():
538 options["include_package_data"] = SetupCfgUtilities.toString(True) 571 options["include_package_data"] = SetupCfgUtilities.toString(True)
539 packageData = {} # placeholder section 572 packageData = {} # placeholder section
540 else: 573 else:
541 packageData = None 574 packageData = None
542 575
543 modules = [] 576 modules = []
544 for row in range(self.modulesList.count()): 577 for row in range(self.modulesList.count()):
545 modules.append(self.modulesList.item(row).text()) 578 modules.append(self.modulesList.item(row).text())
546 if modules: 579 if modules:
547 options["py_modules"] = SetupCfgUtilities.toString(modules) 580 options["py_modules"] = SetupCfgUtilities.toString(modules)
548 581
549 if self.entryPointsList.topLevelItemCount(): 582 if self.entryPointsList.topLevelItemCount():
550 entryPoints = { 583 entryPoints = {
551 "console_scripts": {}, 584 "console_scripts": {},
552 "gui_scripts": {}, 585 "gui_scripts": {},
553 } 586 }
554 for row in range(self.entryPointsList.topLevelItemCount()): 587 for row in range(self.entryPointsList.topLevelItemCount()):
555 itm = self.entryPointsList.topLevelItem(row) 588 itm = self.entryPointsList.topLevelItem(row)
556 entryPoints[itm.data(0, Qt.ItemDataRole.UserRole)][ 589 entryPoints[itm.data(0, Qt.ItemDataRole.UserRole)][
557 itm.text(1)] = itm.text(2) 590 itm.text(1)
591 ] = itm.text(2)
558 for epType in list(entryPoints.keys()): 592 for epType in list(entryPoints.keys()):
559 if entryPoints[epType]: 593 if entryPoints[epType]:
560 entryPoints[epType] = SetupCfgUtilities.toString( 594 entryPoints[epType] = SetupCfgUtilities.toString(
561 entryPoints[epType]) 595 entryPoints[epType]
596 )
562 else: 597 else:
563 del entryPoints[epType] 598 del entryPoints[epType]
564 else: 599 else:
565 entryPoints = {} 600 entryPoints = {}
566 601
567 configDict = { 602 configDict = {
568 "metadata": metadata, 603 "metadata": metadata,
569 "options": options, 604 "options": options,
570 "options.packages.find": findOptions, 605 "options.packages.find": findOptions,
571 } 606 }
572 if packageData is not None: 607 if packageData is not None:
573 configDict["options.package_data"] = packageData 608 configDict["options.package_data"] = packageData
574 if entryPoints: 609 if entryPoints:
575 configDict["options.entry_points"] = entryPoints 610 configDict["options.entry_points"] = entryPoints
576 611
577 cparser = configparser.ConfigParser() 612 cparser = configparser.ConfigParser()
578 cparser.read_dict(configDict) 613 cparser.read_dict(configDict)
579 sio = io.StringIO() 614 sio = io.StringIO()
580 cparser.write(sio) 615 cparser.write(sio)
581 sourceCode = sio.getvalue() 616 sourceCode = sio.getvalue()
582 return sourceCode 617 return sourceCode
583 618
584 def __getPyprojectCode(self): 619 def __getPyprojectCode(self):
585 """ 620 """
586 Private method to get the source code for a 'pyproject.toml' file. 621 Private method to get the source code for a 'pyproject.toml' file.
587 622
588 @return generated code 623 @return generated code
589 @rtype str 624 @rtype str
590 """ 625 """
591 doc = tomlkit.document() 626 doc = tomlkit.document()
592 627
593 buildSystem = tomlkit.table() 628 buildSystem = tomlkit.table()
594 buildSystem["requires"] = ["setuptools>=61.0.0", "wheel"] 629 buildSystem["requires"] = ["setuptools>=61.0.0", "wheel"]
595 buildSystem["build-backend"] = "setuptools.build_meta" 630 buildSystem["build-backend"] = "setuptools.build_meta"
596 doc["build-system"] = buildSystem 631 doc["build-system"] = buildSystem
597 632
598 project = tomlkit.table() 633 project = tomlkit.table()
599 project["name"] = self.nameEdit.text() 634 project["name"] = self.nameEdit.text()
600 project["version"] = self.versionEdit.text() 635 project["version"] = self.versionEdit.text()
601 636
602 if self.summaryEdit.text(): 637 if self.summaryEdit.text():
603 project["description"] = self.summaryEdit.text() 638 project["description"] = self.summaryEdit.text()
604 639
605 if self.descriptionEdit.toPlainText(): 640 if self.descriptionEdit.toPlainText():
606 if self.descriptionFromFilesCheckBox.isChecked(): 641 if self.descriptionFromFilesCheckBox.isChecked():
607 project["readme"] = self.descriptionEdit.toPlainText().splitlines()[0] 642 project["readme"] = self.descriptionEdit.toPlainText().splitlines()[0]
608 else: 643 else:
609 readme = tomlkit.table() 644 readme = tomlkit.table()
610 readme["text"] = self.descriptionEdit.toPlainText() 645 readme["text"] = self.descriptionEdit.toPlainText()
611 readme["content-type"] = ( 646 readme[
612 self.descriptionContentTypeComboBox.currentData() 647 "content-type"
613 ) 648 ] = self.descriptionContentTypeComboBox.currentData()
614 project["readme"] = readme 649 project["readme"] = readme
615 650
616 if self.authorEdit.text(): 651 if self.authorEdit.text():
617 authors = tomlkit.array() 652 authors = tomlkit.array()
618 author = tomlkit.inline_table() 653 author = tomlkit.inline_table()
619 author["name"] = self.authorEdit.text() 654 author["name"] = self.authorEdit.text()
620 author["email"] = self.authorEmailEdit.text() 655 author["email"] = self.authorEmailEdit.text()
621 authors.append(author) 656 authors.append(author)
622 project["authors"] = authors 657 project["authors"] = authors
623 658
624 if self.maintainerEdit.text(): 659 if self.maintainerEdit.text():
625 maintainers = tomlkit.array() 660 maintainers = tomlkit.array()
626 maintainer = tomlkit.inline_table() 661 maintainer = tomlkit.inline_table()
627 maintainer["name"] = self.maintainerEdit.text() 662 maintainer["name"] = self.maintainerEdit.text()
628 maintainer["email"] = self.maintainerEmailEdit.text() 663 maintainer["email"] = self.maintainerEmailEdit.text()
629 maintainers.append(maintainer) 664 maintainers.append(maintainer)
630 project["maintainers"] = maintainers 665 project["maintainers"] = maintainers
631 666
632 urls = tomlkit.table() 667 urls = tomlkit.table()
633 urls["Homepage"] = self.homePageUrlEdit.text() 668 urls["Homepage"] = self.homePageUrlEdit.text()
634 if self.downloadUrlEdit.text(): 669 if self.downloadUrlEdit.text():
635 urls["Download"] = self.downloadUrlEdit.text() 670 urls["Download"] = self.downloadUrlEdit.text()
636 671
637 if self.projectUrlsList.topLevelItemCount(): 672 if self.projectUrlsList.topLevelItemCount():
638 for row in range(self.projectUrlsList.topLevelItemCount()): 673 for row in range(self.projectUrlsList.topLevelItemCount()):
639 urlItem = self.projectUrlsList.topLevelItem(row) 674 urlItem = self.projectUrlsList.topLevelItem(row)
640 urls[urlItem.text(0)] = urlItem.text(1) 675 urls[urlItem.text(0)] = urlItem.text(1)
641 project["urls"] = urls 676 project["urls"] = urls
642 677
643 classifiers = [] 678 classifiers = []
644 if not self.licenseClassifierCheckBox.isChecked(): 679 if not self.licenseClassifierCheckBox.isChecked():
645 licenseTbl = tomlkit.table() 680 licenseTbl = tomlkit.table()
646 licenseTbl["text"] = self.licenseEdit.text() 681 licenseTbl["text"] = self.licenseEdit.text()
647 project["license"] = licenseTbl 682 project["license"] = licenseTbl
648 else: 683 else:
649 classifiers.append( 684 classifiers.append(
650 self.licenseClassifierComboBox.itemData( 685 self.licenseClassifierComboBox.itemData(
651 self.licenseClassifierComboBox.currentIndex())) 686 self.licenseClassifierComboBox.currentIndex()
652 687 )
688 )
689
653 if self.developmentStatusComboBox.currentIndex() != 0: 690 if self.developmentStatusComboBox.currentIndex() != 0:
654 classifiers.append(self.developmentStatusComboBox.currentData()) 691 classifiers.append(self.developmentStatusComboBox.currentData())
655 692
656 itm = self.classifiersList.topLevelItem(0) 693 itm = self.classifiersList.topLevelItem(0)
657 while itm: 694 while itm:
658 itm.setExpanded(True) 695 itm.setExpanded(True)
659 if itm.checkState(0) == Qt.CheckState.Checked: 696 if itm.checkState(0) == Qt.CheckState.Checked:
660 classifiers.append(itm.data(0, Qt.ItemDataRole.UserRole)) 697 classifiers.append(itm.data(0, Qt.ItemDataRole.UserRole))
661 itm = self.classifiersList.itemBelow(itm) 698 itm = self.classifiersList.itemBelow(itm)
662 699
663 # cleanup classifiers list - remove all invalid entries 700 # cleanup classifiers list - remove all invalid entries
664 classifiers = [c for c in classifiers if bool(c)] 701 classifiers = [c for c in classifiers if bool(c)]
665 if classifiers: 702 if classifiers:
666 classifiersArray = tomlkit.array() 703 classifiersArray = tomlkit.array()
667 for classifier in classifiers: 704 for classifier in classifiers:
668 classifiersArray.add_line(classifier) 705 classifiersArray.add_line(classifier)
669 classifiersArray.append(tomlkit.nl()) 706 classifiersArray.append(tomlkit.nl())
670 project["classifiers"] = classifiersArray 707 project["classifiers"] = classifiersArray
671 708
672 if self.keywordsEdit.text(): 709 if self.keywordsEdit.text():
673 keywords = tomlkit.array() 710 keywords = tomlkit.array()
674 for kw in self.keywordsEdit.text().split(): 711 for kw in self.keywordsEdit.text().split():
675 keywords.add_line(kw) 712 keywords.add_line(kw)
676 keywords.append(tomlkit.nl()) 713 keywords.append(tomlkit.nl())
677 project["keywords"] = keywords 714 project["keywords"] = keywords
678 715
679 if self.pyVersionEdit.text(): 716 if self.pyVersionEdit.text():
680 project["requires-python"] = self.pyVersionEdit.text() 717 project["requires-python"] = self.pyVersionEdit.text()
681 718
682 if self.entryPointsList.topLevelItemCount(): 719 if self.entryPointsList.topLevelItemCount():
683 entryPoints = { 720 entryPoints = {
684 "console_scripts": {}, 721 "console_scripts": {},
685 "gui_scripts": {}, 722 "gui_scripts": {},
686 } 723 }
687 for row in range(self.entryPointsList.topLevelItemCount()): 724 for row in range(self.entryPointsList.topLevelItemCount()):
688 itm = self.entryPointsList.topLevelItem(row) 725 itm = self.entryPointsList.topLevelItem(row)
689 entryPoints[itm.data(0, Qt.ItemDataRole.UserRole)][ 726 entryPoints[itm.data(0, Qt.ItemDataRole.UserRole)][
690 itm.text(1)] = itm.text(2) 727 itm.text(1)
691 728 ] = itm.text(2)
729
692 if entryPoints["console_scripts"]: 730 if entryPoints["console_scripts"]:
693 scripts = tomlkit.table() 731 scripts = tomlkit.table()
694 for name, function in entryPoints["console_scripts"].items(): 732 for name, function in entryPoints["console_scripts"].items():
695 scripts[name] = function 733 scripts[name] = function
696 project["scripts"] = scripts 734 project["scripts"] = scripts
697 735
698 if entryPoints["gui_scripts"]: 736 if entryPoints["gui_scripts"]:
699 guiScripts = tomlkit.table() 737 guiScripts = tomlkit.table()
700 for name, function in entryPoints["gui_scripts"].items(): 738 for name, function in entryPoints["gui_scripts"].items():
701 guiScripts[name] = function 739 guiScripts[name] = function
702 project["gui-scripts"] = guiScripts 740 project["gui-scripts"] = guiScripts
703 741
704 # placeholder 742 # placeholder
705 dependencies = tomlkit.array() 743 dependencies = tomlkit.array()
706 dependencies.append(tomlkit.comment( 744 dependencies.append(
707 "TODO: enter project dependencies " # __NO-TASK__ 745 tomlkit.comment("TODO: enter project dependencies ") # __NO-TASK__
708 )) 746 )
709 project["dependencies"] = dependencies 747 project["dependencies"] = dependencies
710 748
711 doc["project"] = project 749 doc["project"] = project
712 750
713 setuptools = tomlkit.table() 751 setuptools = tomlkit.table()
714 752
715 platforms = self.platformsEdit.toPlainText().splitlines() 753 platforms = self.platformsEdit.toPlainText().splitlines()
716 if platforms: 754 if platforms:
717 platformsArray = tomlkit.array() 755 platformsArray = tomlkit.array()
718 for plt in platforms: 756 for plt in platforms:
719 platformsArray.add_line(plt) 757 platformsArray.add_line(plt)
720 platformsArray.append(tomlkit.nl()) 758 platformsArray.append(tomlkit.nl())
721 setuptools["platforms"] = platformsArray 759 setuptools["platforms"] = platformsArray
722 760
723 setuptools["include-package-data"] = self.includePackageDataCheckBox.isChecked() 761 setuptools["include-package-data"] = self.includePackageDataCheckBox.isChecked()
724 if self.includePackageDataCheckBox.isChecked(): 762 if self.includePackageDataCheckBox.isChecked():
725 # placeholder 763 # placeholder
726 setuptools["package-data"] = tomlkit.table() 764 setuptools["package-data"] = tomlkit.table()
727 setuptools["package-data"].add(tomlkit.comment( 765 setuptools["package-data"].add(
728 "TODO: enter package data patterns" # __NO-TASK__ 766 tomlkit.comment("TODO: enter package data patterns") # __NO-TASK__
729 )) 767 )
730 768
731 if self.modulesList.count(): 769 if self.modulesList.count():
732 modulesArray = tomlkit.array() 770 modulesArray = tomlkit.array()
733 for row in range(self.modulesList.count()): 771 for row in range(self.modulesList.count()):
734 modulesArray.add_line(self.modulesList.item(row).text()) 772 modulesArray.add_line(self.modulesList.item(row).text())
735 modulesArray.append(tomlkit.nl()) 773 modulesArray.append(tomlkit.nl())
736 setuptools["py-modules"] = modulesArray 774 setuptools["py-modules"] = modulesArray
737 775
738 findspec = tomlkit.table() 776 findspec = tomlkit.table()
739 src = Utilities.fromNativeSeparators(self.sourceDirectoryPicker.text()) 777 src = Utilities.fromNativeSeparators(self.sourceDirectoryPicker.text())
740 excludePatterns = [] 778 excludePatterns = []
741 for row in range(self.excludePatternList.count()): 779 for row in range(self.excludePatternList.count()):
742 excludePatterns.append( 780 excludePatterns.append(self.excludePatternList.item(row).text())
743 self.excludePatternList.item(row).text())
744 if src: 781 if src:
745 findspec["where"] = [ericApp().getObject("Project").getRelativePath(src)] 782 findspec["where"] = [ericApp().getObject("Project").getRelativePath(src)]
746 if excludePatterns: 783 if excludePatterns:
747 excludePatternsArray = tomlkit.array() 784 excludePatternsArray = tomlkit.array()
748 for pattern in excludePatterns: 785 for pattern in excludePatterns:
749 excludePatternsArray.add_line(pattern) 786 excludePatternsArray.add_line(pattern)
750 excludePatternsArray.append(tomlkit.nl()) 787 excludePatternsArray.append(tomlkit.nl())
751 findspec["exclude"] = excludePatternsArray 788 findspec["exclude"] = excludePatternsArray
752 789
753 if bool(findspec): 790 if bool(findspec):
754 setuptools["packages"] = tomlkit.table(is_super_table=True) 791 setuptools["packages"] = tomlkit.table(is_super_table=True)
755 setuptools["packages"]["find"] = findspec 792 setuptools["packages"]["find"] = findspec
756 793
757 doc["tool"] = tomlkit.table(is_super_table=True) 794 doc["tool"] = tomlkit.table(is_super_table=True)
758 doc["tool"]["setuptools"] = setuptools 795 doc["tool"]["setuptools"] = setuptools
759 796
760 sourceCode = tomlkit.dumps(doc) 797 sourceCode = tomlkit.dumps(doc)
761 return sourceCode 798 return sourceCode
762 799
763 @pyqtSlot() 800 @pyqtSlot()
764 def accept(self): 801 def accept(self):
765 """ 802 """
766 Public slot to handle pressing the OK button. 803 Public slot to handle pressing the OK button.
767 """ 804 """
768 line, index = self.__editor.getCursorPosition() 805 line, index = self.__editor.getCursorPosition()
769 indLevel = self.__editor.indentation(line) // self.__editor.indentationWidth() 806 indLevel = self.__editor.indentation(line) // self.__editor.indentationWidth()
770 indString = ( 807 indString = (
771 '\t' 808 "\t"
772 if self.__editor.indentationsUseTabs() else 809 if self.__editor.indentationsUseTabs()
773 self.__editor.indentationWidth() * ' ' 810 else self.__editor.indentationWidth() * " "
774 ) 811 )
775 812
776 if self.__category == "setup.py": 813 if self.__category == "setup.py":
777 sourceCode = self.__getSetupPyCode(indLevel, indString) 814 sourceCode = self.__getSetupPyCode(indLevel, indString)
778 elif self.__category == "setup.cfg": 815 elif self.__category == "setup.cfg":
779 sourceCode = self.__getSetupCfgCode() 816 sourceCode = self.__getSetupCfgCode()
780 elif self.__category == "pyproject.toml": 817 elif self.__category == "pyproject.toml":
781 sourceCode = self.__getPyprojectCode() 818 sourceCode = self.__getPyprojectCode()
782 else: 819 else:
783 # should not happen, but play it safe 820 # should not happen, but play it safe
784 sourceCode = "" 821 sourceCode = ""
785 822
786 if sourceCode: 823 if sourceCode:
787 line, index = self.__editor.getCursorPosition() 824 line, index = self.__editor.getCursorPosition()
788 # It should be done this way to allow undo 825 # It should be done this way to allow undo
789 self.__editor.beginUndoAction() 826 self.__editor.beginUndoAction()
790 self.__editor.insertAt(sourceCode, line, index) 827 self.__editor.insertAt(sourceCode, line, index)
791 self.__editor.endUndoAction() 828 self.__editor.endUndoAction()
792 829
793 super().accept() 830 super().accept()
794 831
795 @pyqtSlot() 832 @pyqtSlot()
796 def on_projectButton_clicked(self): 833 def on_projectButton_clicked(self):
797 """ 834 """
798 Private slot to populate some fields with data retrieved from the 835 Private slot to populate some fields with data retrieved from the
799 current project. 836 current project.
800 """ 837 """
801 project = ericApp().getObject("Project") 838 project = ericApp().getObject("Project")
802 839
803 self.nameEdit.setText(project.getProjectName()) 840 self.nameEdit.setText(project.getProjectName())
804 try: 841 try:
805 self.versionEdit.setText(project.getProjectVersion()) 842 self.versionEdit.setText(project.getProjectVersion())
806 self.authorEdit.setText(project.getProjectAuthor()) 843 self.authorEdit.setText(project.getProjectAuthor())
807 self.authorEmailEdit.setText(project.getProjectAuthorEmail()) 844 self.authorEmailEdit.setText(project.getProjectAuthorEmail())
809 except AttributeError: 846 except AttributeError:
810 self.versionEdit.setText(project.pdata["VERSION"][0]) 847 self.versionEdit.setText(project.pdata["VERSION"][0])
811 self.authorEdit.setText(project.pdata["AUTHOR"][0]) 848 self.authorEdit.setText(project.pdata["AUTHOR"][0])
812 self.authorEmailEdit.setText(project.pdata["EMAIL"][0]) 849 self.authorEmailEdit.setText(project.pdata["EMAIL"][0])
813 description = project.pdata["DESCRIPTION"][0] 850 description = project.pdata["DESCRIPTION"][0]
814 851
815 summary = ( 852 summary = description.split(".", 1)[0].replace("\r", "").replace("\n", "") + "."
816 description.split(".", 1)[0].replace("\r", "").replace("\n", "") +
817 "."
818 )
819 self.summaryEdit.setText(summary) 853 self.summaryEdit.setText(summary)
820 self.descriptionEdit.setPlainText(description) 854 self.descriptionEdit.setPlainText(description)
821 855
822 self.packageRootPicker.setText(project.getProjectPath()) 856 self.packageRootPicker.setText(project.getProjectPath())
823 857
824 # prevent overwriting of entries by disabling the button 858 # prevent overwriting of entries by disabling the button
825 self.projectButton.setEnabled(False) 859 self.projectButton.setEnabled(False)
826 860
827 def __getStartDir(self): 861 def __getStartDir(self):
828 """ 862 """
829 Private method to get the start directory for selection dialogs. 863 Private method to get the start directory for selection dialogs.
830 864
831 @return start directory 865 @return start directory
832 @rtype str 866 @rtype str
833 """ 867 """
834 return (Preferences.getMultiProject("Workspace") or 868 return Preferences.getMultiProject("Workspace") or Utilities.getHomeDir()
835 Utilities.getHomeDir()) 869
836
837 @pyqtSlot() 870 @pyqtSlot()
838 def on_entryPointsList_itemSelectionChanged(self): 871 def on_entryPointsList_itemSelectionChanged(self):
839 """ 872 """
840 Private slot to handle a change of selected items of the 873 Private slot to handle a change of selected items of the
841 entry points list. 874 entry points list.
842 """ 875 """
843 self.deleteEntryPointButton.setEnabled( 876 self.deleteEntryPointButton.setEnabled(
844 bool(self.entryPointsList.selectedItems())) 877 bool(self.entryPointsList.selectedItems())
878 )
845 self.editEntryPointButton.setEnabled( 879 self.editEntryPointButton.setEnabled(
846 len(self.entryPointsList.selectedItems()) == 1) 880 len(self.entryPointsList.selectedItems()) == 1
847 881 )
882
848 @pyqtSlot() 883 @pyqtSlot()
849 def on_deleteEntryPointButton_clicked(self): 884 def on_deleteEntryPointButton_clicked(self):
850 """ 885 """
851 Private slot to delete the selected entry point items. 886 Private slot to delete the selected entry point items.
852 """ 887 """
853 for itm in self.entryPointsList.selectedItems(): 888 for itm in self.entryPointsList.selectedItems():
854 self.entryPointsList.takeTopLevelItem(self.entryPointsList.row(itm)) 889 self.entryPointsList.takeTopLevelItem(self.entryPointsList.row(itm))
855 del itm 890 del itm
856 891
857 @pyqtSlot() 892 @pyqtSlot()
858 def on_addEntryPointButton_clicked(self): 893 def on_addEntryPointButton_clicked(self):
859 """ 894 """
860 Private slot to add an entry point to the list. 895 Private slot to add an entry point to the list.
861 """ 896 """
862 project = ericApp().getObject("Project") 897 project = ericApp().getObject("Project")
863 rootDir = ( 898 rootDir = project.getProjectPath() if project.isOpen() else ""
864 project.getProjectPath()
865 if project.isOpen() else
866 ""
867 )
868 dlg = AddEntryPointDialog(rootDir, parent=self) 899 dlg = AddEntryPointDialog(rootDir, parent=self)
869 if dlg.exec() == QDialog.DialogCode.Accepted: 900 if dlg.exec() == QDialog.DialogCode.Accepted:
870 epType, epCategory, name, script = dlg.getEntryPoint() 901 epType, epCategory, name, script = dlg.getEntryPoint()
871 itm = QTreeWidgetItem(self.entryPointsList, [epType, name, script]) 902 itm = QTreeWidgetItem(self.entryPointsList, [epType, name, script])
872 itm.setData(0, Qt.ItemDataRole.UserRole, epCategory) 903 itm.setData(0, Qt.ItemDataRole.UserRole, epCategory)
873 904
874 @pyqtSlot() 905 @pyqtSlot()
875 def on_editEntryPointButton_clicked(self): 906 def on_editEntryPointButton_clicked(self):
876 """ 907 """
877 Private slot to edit the selected entry point. 908 Private slot to edit the selected entry point.
878 """ 909 """
879 project = ericApp().getObject("Project") 910 project = ericApp().getObject("Project")
880 rootDir = ( 911 rootDir = project.getProjectPath() if project.isOpen() else ""
881 project.getProjectPath()
882 if project.isOpen() else
883 ""
884 )
885 itm = self.entryPointsList.selectedItems()[0] 912 itm = self.entryPointsList.selectedItems()[0]
886 dlg = AddEntryPointDialog(rootDir, epType=itm.text(0), name=itm.text(1), 913 dlg = AddEntryPointDialog(
887 script=itm.text(2), parent=self) 914 rootDir,
915 epType=itm.text(0),
916 name=itm.text(1),
917 script=itm.text(2),
918 parent=self,
919 )
888 if dlg.exec() == QDialog.DialogCode.Accepted: 920 if dlg.exec() == QDialog.DialogCode.Accepted:
889 epType, epCategory, name, script = dlg.getEntryPoint() 921 epType, epCategory, name, script = dlg.getEntryPoint()
890 itm.setText(0, epType) 922 itm.setText(0, epType)
891 itm.setText(1, name) 923 itm.setText(1, name)
892 itm.setText(2, script) 924 itm.setText(2, script)
893 itm.setData(0, Qt.ItemDataRole.UserRole, epCategory) 925 itm.setData(0, Qt.ItemDataRole.UserRole, epCategory)
894 926
895 @pyqtSlot() 927 @pyqtSlot()
896 def on_modulesList_itemSelectionChanged(self): 928 def on_modulesList_itemSelectionChanged(self):
897 """ 929 """
898 Private slot to handle a change of selected items of the 930 Private slot to handle a change of selected items of the
899 modules list. 931 modules list.
900 """ 932 """
901 self.deleteModuleButton.setEnabled( 933 self.deleteModuleButton.setEnabled(bool(self.modulesList.selectedItems()))
902 bool(self.modulesList.selectedItems())) 934
903
904 @pyqtSlot() 935 @pyqtSlot()
905 def on_deleteModuleButton_clicked(self): 936 def on_deleteModuleButton_clicked(self):
906 """ 937 """
907 Private slot to delete the selected module items. 938 Private slot to delete the selected module items.
908 """ 939 """
909 for itm in self.modulesList.selectedItems(): 940 for itm in self.modulesList.selectedItems():
910 self.modulesList.takeItem(self.modulesList.row(itm)) 941 self.modulesList.takeItem(self.modulesList.row(itm))
911 del itm 942 del itm
912 943
913 @pyqtSlot() 944 @pyqtSlot()
914 def on_addModuleButton_clicked(self): 945 def on_addModuleButton_clicked(self):
915 """ 946 """
916 Private slot to add Python modules to the list. 947 Private slot to add Python modules to the list.
917 """ 948 """
918 startDir = self.packageRootPicker.text() or self.__getStartDir() 949 startDir = self.packageRootPicker.text() or self.__getStartDir()
919 modulesList = EricFileDialog.getOpenFileNames( 950 modulesList = EricFileDialog.getOpenFileNames(
920 self, 951 self,
921 self.tr("Add Python Modules"), 952 self.tr("Add Python Modules"),
922 startDir, 953 startDir,
923 self.tr("Python Files (*.py)")) 954 self.tr("Python Files (*.py)"),
955 )
924 for module in modulesList: 956 for module in modulesList:
925 module = module.replace( 957 module = module.replace(Utilities.toNativeSeparators(startDir), "")
926 Utilities.toNativeSeparators(startDir), "")
927 if module.startswith(("\\", "/")): 958 if module.startswith(("\\", "/")):
928 module = module[1:] 959 module = module[1:]
929 if module: 960 if module:
930 QListWidgetItem( 961 QListWidgetItem(
931 str(pathlib.Path(module).with_suffix("")) 962 str(pathlib.Path(module).with_suffix(""))
932 .replace("\\", ".") 963 .replace("\\", ".")
933 .replace("/", "."), 964 .replace("/", "."),
934 self.modulesList 965 self.modulesList,
935 ) 966 )
936 967
937 @pyqtSlot() 968 @pyqtSlot()
938 def on_excludePatternList_itemSelectionChanged(self): 969 def on_excludePatternList_itemSelectionChanged(self):
939 """ 970 """
940 Private slot to handle a change of selected items of the 971 Private slot to handle a change of selected items of the
941 exclude pattern list. 972 exclude pattern list.
942 """ 973 """
943 self.deleteExcludePatternButton.setEnabled( 974 self.deleteExcludePatternButton.setEnabled(
944 bool(self.excludePatternList.selectedItems())) 975 bool(self.excludePatternList.selectedItems())
945 976 )
977
946 @pyqtSlot() 978 @pyqtSlot()
947 def on_deleteExcludePatternButton_clicked(self): 979 def on_deleteExcludePatternButton_clicked(self):
948 """ 980 """
949 Private slot to delete the selected exclude pattern items. 981 Private slot to delete the selected exclude pattern items.
950 """ 982 """
951 for itm in self.excludePatternList.selectedItems(): 983 for itm in self.excludePatternList.selectedItems():
952 self.excludePatternList.takeItem( 984 self.excludePatternList.takeItem(self.excludePatternList.row(itm))
953 self.excludePatternList.row(itm))
954 del itm 985 del itm
955 986
956 @pyqtSlot() 987 @pyqtSlot()
957 def on_addExludePatternButton_clicked(self): 988 def on_addExludePatternButton_clicked(self):
958 """ 989 """
959 Private slot to add an exclude pattern to the list. 990 Private slot to add an exclude pattern to the list.
960 """ 991 """
961 pattern = ( 992 pattern = self.excludePatternEdit.text().replace("\\", ".").replace("/", ".")
962 self.excludePatternEdit.text().replace("\\", ".").replace("/", ".")
963 )
964 if not self.excludePatternList.findItems( 993 if not self.excludePatternList.findItems(
965 pattern, 994 pattern, Qt.MatchFlag.MatchExactly | Qt.MatchFlag.MatchCaseSensitive
966 Qt.MatchFlag.MatchExactly | Qt.MatchFlag.MatchCaseSensitive
967 ): 995 ):
968 QListWidgetItem(pattern, self.excludePatternList) 996 QListWidgetItem(pattern, self.excludePatternList)
969 997
970 @pyqtSlot(str) 998 @pyqtSlot(str)
971 def on_excludePatternEdit_textChanged(self, txt): 999 def on_excludePatternEdit_textChanged(self, txt):
972 """ 1000 """
973 Private slot to handle a change of the exclude pattern text. 1001 Private slot to handle a change of the exclude pattern text.
974 1002
975 @param txt text of the line edit 1003 @param txt text of the line edit
976 @type str 1004 @type str
977 """ 1005 """
978 self.addExludePatternButton.setEnabled(bool(txt)) 1006 self.addExludePatternButton.setEnabled(bool(txt))
979 1007
980 @pyqtSlot() 1008 @pyqtSlot()
981 def on_excludePatternEdit_returnPressed(self): 1009 def on_excludePatternEdit_returnPressed(self):
982 """ 1010 """
983 Private slot handling a press of the return button of the 1011 Private slot handling a press of the return button of the
984 exclude pattern edit. 1012 exclude pattern edit.
985 """ 1013 """
986 self.on_addExludePatternButton_clicked() 1014 self.on_addExludePatternButton_clicked()
987 1015
988 @pyqtSlot() 1016 @pyqtSlot()
989 def on_urlDeleteButton_clicked(self): 1017 def on_urlDeleteButton_clicked(self):
990 """ 1018 """
991 Private slot to delete the selected URL items. 1019 Private slot to delete the selected URL items.
992 """ 1020 """
993 for itm in self.projectUrlsList.selectedItems(): 1021 for itm in self.projectUrlsList.selectedItems():
994 self.projectUrlsList.takeTopLevelItem(self.projectUrlsList.row(itm)) 1022 self.projectUrlsList.takeTopLevelItem(self.projectUrlsList.row(itm))
995 del itm 1023 del itm
996 1024
997 @pyqtSlot() 1025 @pyqtSlot()
998 def on_urlAddButton_clicked(self): 1026 def on_urlAddButton_clicked(self):
999 """ 1027 """
1000 Private slot to add a project URL to the list. 1028 Private slot to add a project URL to the list.
1001 """ 1029 """
1002 dlg = AddProjectUrlDialog(parent=self) 1030 dlg = AddProjectUrlDialog(parent=self)
1003 if dlg.exec() == QDialog.DialogCode.Accepted: 1031 if dlg.exec() == QDialog.DialogCode.Accepted:
1004 name, url = dlg.getUrl() 1032 name, url = dlg.getUrl()
1005 QTreeWidgetItem(self.projectUrlsList, [name, url]) 1033 QTreeWidgetItem(self.projectUrlsList, [name, url])
1006 1034
1007 @pyqtSlot() 1035 @pyqtSlot()
1008 def on_urlEditButton_clicked(self): 1036 def on_urlEditButton_clicked(self):
1009 """ 1037 """
1010 Private slot to edit the selected project URL. 1038 Private slot to edit the selected project URL.
1011 """ 1039 """
1013 dlg = AddProjectUrlDialog(name=itm.text(0), url=itm.text(1), parent=self) 1041 dlg = AddProjectUrlDialog(name=itm.text(0), url=itm.text(1), parent=self)
1014 if dlg.exec() == QDialog.DialogCode.Accepted: 1042 if dlg.exec() == QDialog.DialogCode.Accepted:
1015 name, url = dlg.getUrl() 1043 name, url = dlg.getUrl()
1016 itm.setText(0, name) 1044 itm.setText(0, name)
1017 itm.setText(1, url) 1045 itm.setText(1, url)
1018 1046
1019 @pyqtSlot() 1047 @pyqtSlot()
1020 def on_projectUrlsList_itemSelectionChanged(self): 1048 def on_projectUrlsList_itemSelectionChanged(self):
1021 """ 1049 """
1022 Private slot to handle a change of selected items of the 1050 Private slot to handle a change of selected items of the
1023 project URLs list. 1051 project URLs list.

eric ide

mercurial