src/eric7/Preferences/ProgramsDialog.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
10 import os 10 import os
11 import re 11 import re
12 12
13 from PyQt6.QtCore import pyqtSlot, Qt, QProcess 13 from PyQt6.QtCore import pyqtSlot, Qt, QProcess
14 from PyQt6.QtWidgets import ( 14 from PyQt6.QtWidgets import (
15 QApplication, QTreeWidgetItem, QHeaderView, QDialog, QDialogButtonBox 15 QApplication,
16 QTreeWidgetItem,
17 QHeaderView,
18 QDialog,
19 QDialogButtonBox,
16 ) 20 )
17 21
18 from EricWidgets.EricApplication import ericApp 22 from EricWidgets.EricApplication import ericApp
19 from EricGui.EricOverrideCursor import EricOverrideCursor 23 from EricGui.EricOverrideCursor import EricOverrideCursor
20 24
27 31
28 class ProgramsDialog(QDialog, Ui_ProgramsDialog): 32 class ProgramsDialog(QDialog, Ui_ProgramsDialog):
29 """ 33 """
30 Class implementing the Programs page. 34 Class implementing the Programs page.
31 """ 35 """
36
32 ToolAvailableRole = Qt.ItemDataRole.UserRole + 1 37 ToolAvailableRole = Qt.ItemDataRole.UserRole + 1
33 38
34 def __init__(self, parent=None): 39 def __init__(self, parent=None):
35 """ 40 """
36 Constructor 41 Constructor
37 42
38 @param parent The parent widget of this dialog. (QWidget) 43 @param parent The parent widget of this dialog. (QWidget)
39 """ 44 """
40 super().__init__(parent) 45 super().__init__(parent)
41 self.setupUi(self) 46 self.setupUi(self)
42 self.setObjectName("ProgramsDialog") 47 self.setObjectName("ProgramsDialog")
43 self.setWindowFlags(Qt.WindowType.Window) 48 self.setWindowFlags(Qt.WindowType.Window)
44 49
45 self.__hasSearched = False 50 self.__hasSearched = False
46 51
47 self.programsList.headerItem().setText( 52 self.programsList.headerItem().setText(self.programsList.columnCount(), "")
48 self.programsList.columnCount(), "") 53
49
50 self.searchButton = self.buttonBox.addButton( 54 self.searchButton = self.buttonBox.addButton(
51 self.tr("Search"), QDialogButtonBox.ButtonRole.ActionRole) 55 self.tr("Search"), QDialogButtonBox.ButtonRole.ActionRole
52 self.searchButton.setToolTip( 56 )
53 self.tr("Press to search for programs")) 57 self.searchButton.setToolTip(self.tr("Press to search for programs"))
54 58
55 self.showComboBox.addItems([ 59 self.showComboBox.addItems(
56 self.tr("All Supported Tools"), 60 [
57 self.tr("Available Tools Only"), 61 self.tr("All Supported Tools"),
58 self.tr("Unavailable Tools Only"), 62 self.tr("Available Tools Only"),
59 ]) 63 self.tr("Unavailable Tools Only"),
60 64 ]
65 )
66
61 def show(self): 67 def show(self):
62 """ 68 """
63 Public slot to show the dialog. 69 Public slot to show the dialog.
64 """ 70 """
65 QDialog.show(self) 71 QDialog.show(self)
66 if not self.__hasSearched: 72 if not self.__hasSearched:
67 self.on_programsSearchButton_clicked() 73 self.on_programsSearchButton_clicked()
68 74
69 def on_buttonBox_clicked(self, button): 75 def on_buttonBox_clicked(self, button):
70 """ 76 """
71 Private slot called by a button of the button box clicked. 77 Private slot called by a button of the button box clicked.
72 78
73 @param button button that was clicked (QAbstractButton) 79 @param button button that was clicked (QAbstractButton)
74 """ 80 """
75 if button == self.searchButton: 81 if button == self.searchButton:
76 self.on_programsSearchButton_clicked() 82 self.on_programsSearchButton_clicked()
77 83
78 @pyqtSlot() 84 @pyqtSlot()
79 def on_programsSearchButton_clicked(self): 85 def on_programsSearchButton_clicked(self):
80 """ 86 """
81 Private slot to search for all supported/required programs. 87 Private slot to search for all supported/required programs.
82 """ 88 """
83 self.programsList.clear() 89 self.programsList.clear()
84 header = self.programsList.header() 90 header = self.programsList.header()
85 header.setSortIndicator(0, Qt.SortOrder.AscendingOrder) 91 header.setSortIndicator(0, Qt.SortOrder.AscendingOrder)
86 header.setSortIndicatorShown(False) 92 header.setSortIndicatorShown(False)
87 93
88 with EricOverrideCursor(): 94 with EricOverrideCursor():
89 # 1. do the Qt programs 95 # 1. do the Qt programs
90 # 1a. Translation Converter 96 # 1a. Translation Converter
91 exe = ( 97 exe = (
92 Utilities.isWindowsPlatform() and 98 Utilities.isWindowsPlatform()
93 "{0}.exe".format(Utilities.generateQtToolName("lrelease")) or 99 and "{0}.exe".format(Utilities.generateQtToolName("lrelease"))
94 Utilities.generateQtToolName("lrelease") 100 or Utilities.generateQtToolName("lrelease")
95 ) 101 )
96 exe = os.path.join(Utilities.getQtBinariesPath(), exe) 102 exe = os.path.join(Utilities.getQtBinariesPath(), exe)
97 version = self.__createProgramEntry( 103 version = self.__createProgramEntry(
98 self.tr("Translation Converter (Qt)"), exe, '-version', 104 self.tr("Translation Converter (Qt)"), exe, "-version", "lrelease", -1
99 'lrelease', -1) 105 )
100 # 1b. Qt Designer 106 # 1b. Qt Designer
101 if Utilities.isWindowsPlatform(): 107 if Utilities.isWindowsPlatform():
102 exe = os.path.join( 108 exe = os.path.join(
103 Utilities.getQtBinariesPath(), 109 Utilities.getQtBinariesPath(),
104 "{0}.exe".format(Utilities.generateQtToolName("designer"))) 110 "{0}.exe".format(Utilities.generateQtToolName("designer")),
111 )
105 elif Utilities.isMacPlatform(): 112 elif Utilities.isMacPlatform():
106 exe = Utilities.getQtMacBundle("designer") 113 exe = Utilities.getQtMacBundle("designer")
107 else: 114 else:
108 exe = os.path.join( 115 exe = os.path.join(
109 Utilities.getQtBinariesPath(), 116 Utilities.getQtBinariesPath(),
110 Utilities.generateQtToolName("designer")) 117 Utilities.generateQtToolName("designer"),
111 self.__createProgramEntry( 118 )
112 self.tr("Qt Designer"), exe, version=version) 119 self.__createProgramEntry(self.tr("Qt Designer"), exe, version=version)
113 # 1c. Qt Linguist 120 # 1c. Qt Linguist
114 if Utilities.isWindowsPlatform(): 121 if Utilities.isWindowsPlatform():
115 exe = os.path.join( 122 exe = os.path.join(
116 Utilities.getQtBinariesPath(), 123 Utilities.getQtBinariesPath(),
117 "{0}.exe".format(Utilities.generateQtToolName("linguist"))) 124 "{0}.exe".format(Utilities.generateQtToolName("linguist")),
125 )
118 elif Utilities.isMacPlatform(): 126 elif Utilities.isMacPlatform():
119 exe = Utilities.getQtMacBundle("linguist") 127 exe = Utilities.getQtMacBundle("linguist")
120 else: 128 else:
121 exe = os.path.join( 129 exe = os.path.join(
122 Utilities.getQtBinariesPath(), 130 Utilities.getQtBinariesPath(),
123 Utilities.generateQtToolName("linguist")) 131 Utilities.generateQtToolName("linguist"),
124 self.__createProgramEntry( 132 )
125 self.tr("Qt Linguist"), exe, version=version) 133 self.__createProgramEntry(self.tr("Qt Linguist"), exe, version=version)
126 # 1d. Qt Assistant 134 # 1d. Qt Assistant
127 if Utilities.isWindowsPlatform(): 135 if Utilities.isWindowsPlatform():
128 exe = os.path.join( 136 exe = os.path.join(
129 Utilities.getQtBinariesPath(), 137 Utilities.getQtBinariesPath(),
130 "{0}.exe".format( 138 "{0}.exe".format(Utilities.generateQtToolName("assistant")),
131 Utilities.generateQtToolName("assistant"))) 139 )
132 elif Utilities.isMacPlatform(): 140 elif Utilities.isMacPlatform():
133 exe = Utilities.getQtMacBundle("assistant") 141 exe = Utilities.getQtMacBundle("assistant")
134 else: 142 else:
135 exe = os.path.join( 143 exe = os.path.join(
136 Utilities.getQtBinariesPath(), 144 Utilities.getQtBinariesPath(),
137 Utilities.generateQtToolName("assistant")) 145 Utilities.generateQtToolName("assistant"),
138 self.__createProgramEntry( 146 )
139 self.tr("Qt Assistant"), exe, version=version) 147 self.__createProgramEntry(self.tr("Qt Assistant"), exe, version=version)
140 148
141 # 2. do the PyQt programs 149 # 2. do the PyQt programs
142 # 2.1 do the PyQt5 programs 150 # 2.1 do the PyQt5 programs
143 # 2.1a. Translation Extractor PyQt5 151 # 2.1a. Translation Extractor PyQt5
144 self.__createProgramEntry( 152 self.__createProgramEntry(
145 self.tr("Translation Extractor (Python, PyQt5)"), 153 self.tr("Translation Extractor (Python, PyQt5)"),
146 Utilities.generatePyQtToolPath("pylupdate5"), 154 Utilities.generatePyQtToolPath("pylupdate5"),
147 '-version', 'pylupdate', -1) 155 "-version",
156 "pylupdate",
157 -1,
158 )
148 # 2.1b. Forms Compiler PyQt5 159 # 2.1b. Forms Compiler PyQt5
149 self.__createProgramEntry( 160 self.__createProgramEntry(
150 self.tr("Forms Compiler (Python, PyQt5)"), 161 self.tr("Forms Compiler (Python, PyQt5)"),
151 Utilities.generatePyQtToolPath("pyuic5", ["py3uic5"]), 162 Utilities.generatePyQtToolPath("pyuic5", ["py3uic5"]),
152 '--version', 'Python User', 4) 163 "--version",
164 "Python User",
165 4,
166 )
153 # 2.1c. Resource Compiler PyQt5 167 # 2.1c. Resource Compiler PyQt5
154 self.__createProgramEntry( 168 self.__createProgramEntry(
155 self.tr("Resource Compiler (Python, PyQt5)"), 169 self.tr("Resource Compiler (Python, PyQt5)"),
156 Utilities.generatePyQtToolPath("pyrcc5"), 170 Utilities.generatePyQtToolPath("pyrcc5"),
157 '-version', '', -1, versionRe='Resource Compiler|pyrcc5') 171 "-version",
158 172 "",
173 -1,
174 versionRe="Resource Compiler|pyrcc5",
175 )
176
159 # 2.2 do the PyQt6 programs 177 # 2.2 do the PyQt6 programs
160 # 2.2a. Translation Extractor PyQt6 178 # 2.2a. Translation Extractor PyQt6
161 self.__createProgramEntry( 179 self.__createProgramEntry(
162 self.tr("Translation Extractor (Python, PyQt6)"), 180 self.tr("Translation Extractor (Python, PyQt6)"),
163 Utilities.generatePyQtToolPath("pylupdate6"), 181 Utilities.generatePyQtToolPath("pylupdate6"),
164 '--version', versionPosition=0) 182 "--version",
183 versionPosition=0,
184 )
165 # 2.2b. Forms Compiler PyQt6 185 # 2.2b. Forms Compiler PyQt6
166 self.__createProgramEntry( 186 self.__createProgramEntry(
167 self.tr("Forms Compiler (Python, PyQt6)"), 187 self.tr("Forms Compiler (Python, PyQt6)"),
168 Utilities.generatePyQtToolPath("pyuic6"), 188 Utilities.generatePyQtToolPath("pyuic6"),
169 '--version', versionPosition=0) 189 "--version",
170 190 versionPosition=0,
191 )
192
171 # 3. do the PySide programs 193 # 3. do the PySide programs
172 # 3.1 do the PySide2 programs 194 # 3.1 do the PySide2 programs
173 # 3.1a. Translation Extractor PySide2 195 # 3.1a. Translation Extractor PySide2
174 self.__createProgramEntry( 196 self.__createProgramEntry(
175 self.tr("Translation Extractor (Python, PySide2)"), 197 self.tr("Translation Extractor (Python, PySide2)"),
176 Utilities.generatePySideToolPath("pyside2-lupdate", variant=2), 198 Utilities.generatePySideToolPath("pyside2-lupdate", variant=2),
177 '-version', '', -1, versionRe='lupdate') 199 "-version",
200 "",
201 -1,
202 versionRe="lupdate",
203 )
178 # 3.1b. Forms Compiler PySide2 204 # 3.1b. Forms Compiler PySide2
179 self.__createProgramEntry( 205 self.__createProgramEntry(
180 self.tr("Forms Compiler (Python, PySide2)"), 206 self.tr("Forms Compiler (Python, PySide2)"),
181 Utilities.generatePySideToolPath("pyside2-uic", variant=2), 207 Utilities.generatePySideToolPath("pyside2-uic", variant=2),
182 '--version', '', -1, versionRe='uic') 208 "--version",
209 "",
210 -1,
211 versionRe="uic",
212 )
183 # 3.1c Resource Compiler PySide2 213 # 3.1c Resource Compiler PySide2
184 self.__createProgramEntry( 214 self.__createProgramEntry(
185 self.tr("Resource Compiler (Python, PySide2)"), 215 self.tr("Resource Compiler (Python, PySide2)"),
186 Utilities.generatePySideToolPath("pyside2-rcc", variant=2), 216 Utilities.generatePySideToolPath("pyside2-rcc", variant=2),
187 '-version', '', -1, versionRe='rcc') 217 "-version",
218 "",
219 -1,
220 versionRe="rcc",
221 )
188 # 3.2 do the PySide5 programs 222 # 3.2 do the PySide5 programs
189 # 3.2a. Translation Extractor PySide6 223 # 3.2a. Translation Extractor PySide6
190 self.__createProgramEntry( 224 self.__createProgramEntry(
191 self.tr("Translation Extractor (Python, PySide6)"), 225 self.tr("Translation Extractor (Python, PySide6)"),
192 Utilities.generatePySideToolPath("pyside6-lupdate", variant=6), 226 Utilities.generatePySideToolPath("pyside6-lupdate", variant=6),
193 '-version', '', -1, versionRe='lupdate') 227 "-version",
228 "",
229 -1,
230 versionRe="lupdate",
231 )
194 # 3.2b. Forms Compiler PySide6 232 # 3.2b. Forms Compiler PySide6
195 self.__createProgramEntry( 233 self.__createProgramEntry(
196 self.tr("Forms Compiler (Python, PySide6)"), 234 self.tr("Forms Compiler (Python, PySide6)"),
197 Utilities.generatePySideToolPath("pyside6-uic", variant=6), 235 Utilities.generatePySideToolPath("pyside6-uic", variant=6),
198 '--version', '', -1, versionRe='uic') 236 "--version",
237 "",
238 -1,
239 versionRe="uic",
240 )
199 # 3.2c Resource Compiler PySide6 241 # 3.2c Resource Compiler PySide6
200 self.__createProgramEntry( 242 self.__createProgramEntry(
201 self.tr("Resource Compiler (Python, PySide6)"), 243 self.tr("Resource Compiler (Python, PySide6)"),
202 Utilities.generatePySideToolPath("pyside6-rcc", variant=6), 244 Utilities.generatePySideToolPath("pyside6-rcc", variant=6),
203 '--version', '', -1, versionRe='rcc') 245 "--version",
204 246 "",
247 -1,
248 versionRe="rcc",
249 )
250
205 # 4. do the Conda program(s) 251 # 4. do the Conda program(s)
206 exe = Preferences.getConda("CondaExecutable") 252 exe = Preferences.getConda("CondaExecutable")
207 if not exe: 253 if not exe:
208 exe = "conda" 254 exe = "conda"
209 if Utilities.isWindowsPlatform(): 255 if Utilities.isWindowsPlatform():
210 exe += ".exe" 256 exe += ".exe"
211 self.__createProgramEntry( 257 self.__createProgramEntry(
212 self.tr("conda Manager"), exe, '--version', 'conda', -1) 258 self.tr("conda Manager"), exe, "--version", "conda", -1
213 259 )
260
214 # 5. do the pip program(s) 261 # 5. do the pip program(s)
215 virtualenvManager = ericApp().getObject("VirtualEnvManager") 262 virtualenvManager = ericApp().getObject("VirtualEnvManager")
216 for venvName in virtualenvManager.getVirtualenvNames(): 263 for venvName in virtualenvManager.getVirtualenvNames():
217 interpreter = virtualenvManager.getVirtualenvInterpreter( 264 interpreter = virtualenvManager.getVirtualenvInterpreter(venvName)
218 venvName)
219 self.__createProgramEntry( 265 self.__createProgramEntry(
220 self.tr("PyPI Package Management"), interpreter, 266 self.tr("PyPI Package Management"),
221 '--version', 'pip', 1, exeModule=["-m", "pip"]) 267 interpreter,
222 268 "--version",
269 "pip",
270 1,
271 exeModule=["-m", "pip"],
272 )
273
223 # 6. do the CORBA and Protobuf programs 274 # 6. do the CORBA and Protobuf programs
224 # 6a. omniORB 275 # 6a. omniORB
225 exe = Preferences.getCorba("omniidl") 276 exe = Preferences.getCorba("omniidl")
226 if not exe: 277 if not exe:
227 exe = "omniidl" 278 exe = "omniidl"
228 if Utilities.isWindowsPlatform(): 279 if Utilities.isWindowsPlatform():
229 exe += ".exe" 280 exe += ".exe"
230 self.__createProgramEntry( 281 self.__createProgramEntry(
231 self.tr("CORBA IDL Compiler"), exe, '-V', 'omniidl', -1) 282 self.tr("CORBA IDL Compiler"), exe, "-V", "omniidl", -1
283 )
232 # 6b. protobuf 284 # 6b. protobuf
233 exe = Preferences.getProtobuf("protoc") 285 exe = Preferences.getProtobuf("protoc")
234 if not exe: 286 if not exe:
235 exe = "protoc" 287 exe = "protoc"
236 if Utilities.isWindowsPlatform(): 288 if Utilities.isWindowsPlatform():
237 exe += ".exe" 289 exe += ".exe"
238 self.__createProgramEntry( 290 self.__createProgramEntry(
239 self.tr("Protobuf Compiler"), exe, '--version', 'libprotoc', 291 self.tr("Protobuf Compiler"), exe, "--version", "libprotoc", -1
240 -1) 292 )
241 # 6c. grpc 293 # 6c. grpc
242 exe = Preferences.getProtobuf("grpcPython") 294 exe = Preferences.getProtobuf("grpcPython")
243 if not exe: 295 if not exe:
244 exe = Globals.getPythonExecutable() 296 exe = Globals.getPythonExecutable()
245 self.__createProgramEntry( 297 self.__createProgramEntry(
246 self.tr("gRPC Compiler"), exe, '--version', 'libprotoc', -1, 298 self.tr("gRPC Compiler"),
247 exeModule=['-m', 'grpc_tools.protoc']) 299 exe,
248 300 "--version",
301 "libprotoc",
302 -1,
303 exeModule=["-m", "grpc_tools.protoc"],
304 )
305
249 # 7. do the spell checking entry 306 # 7. do the spell checking entry
250 try: 307 try:
251 import enchant 308 import enchant
309
252 try: 310 try:
253 text = os.path.dirname(enchant.__file__) 311 text = os.path.dirname(enchant.__file__)
254 except AttributeError: 312 except AttributeError:
255 text = "enchant" 313 text = "enchant"
256 try: 314 try:
258 except AttributeError: 316 except AttributeError:
259 version = self.tr("(unknown)") 317 version = self.tr("(unknown)")
260 except (ImportError, AttributeError, OSError): 318 except (ImportError, AttributeError, OSError):
261 text = "enchant" 319 text = "enchant"
262 version = "" 320 version = ""
263 self.__createEntry( 321 self.__createEntry(self.tr("Spell Checker - PyEnchant"), text, version)
264 self.tr("Spell Checker - PyEnchant"), text, version) 322
265
266 # 8. do the pygments entry 323 # 8. do the pygments entry
267 try: 324 try:
268 import pygments 325 import pygments
326
269 try: 327 try:
270 text = os.path.dirname(pygments.__file__) 328 text = os.path.dirname(pygments.__file__)
271 except AttributeError: 329 except AttributeError:
272 text = "pygments" 330 text = "pygments"
273 try: 331 try:
275 except AttributeError: 333 except AttributeError:
276 version = self.tr("(unknown)") 334 version = self.tr("(unknown)")
277 except (ImportError, AttributeError, OSError): 335 except (ImportError, AttributeError, OSError):
278 text = "pygments" 336 text = "pygments"
279 version = "" 337 version = ""
280 self.__createEntry( 338 self.__createEntry(self.tr("Source Highlighter - Pygments"), text, version)
281 self.tr("Source Highlighter - Pygments"), text, version) 339
282
283 # 9. do the MicroPython related entries 340 # 9. do the MicroPython related entries
284 exe = Preferences.getMicroPython("MpyCrossCompiler") 341 exe = Preferences.getMicroPython("MpyCrossCompiler")
285 if not exe: 342 if not exe:
286 exe = "mpy-cross" 343 exe = "mpy-cross"
287 self.__createProgramEntry( 344 self.__createProgramEntry(
288 self.tr("MicroPython - MPY Cross Compiler"), exe, '--version', 345 self.tr("MicroPython - MPY Cross Compiler"),
289 'MicroPython', 1) 346 exe,
347 "--version",
348 "MicroPython",
349 1,
350 )
290 self.__createProgramEntry( 351 self.__createProgramEntry(
291 self.tr("MicroPython - ESP Tool"), 352 self.tr("MicroPython - ESP Tool"),
292 Globals.getPythonExecutable(), 'version', 353 Globals.getPythonExecutable(),
293 'esptool', -1, exeModule=['-m', 'esptool']) 354 "version",
355 "esptool",
356 -1,
357 exeModule=["-m", "esptool"],
358 )
294 exe = Preferences.getMicroPython("DfuUtilPath") 359 exe = Preferences.getMicroPython("DfuUtilPath")
295 if not exe: 360 if not exe:
296 exe = "dfu-util" 361 exe = "dfu-util"
297 self.__createProgramEntry( 362 self.__createProgramEntry(
298 self.tr("MicroPython - PyBoard Flasher"), exe, '--version', 363 self.tr("MicroPython - PyBoard Flasher"),
299 'dfu-util', -1) 364 exe,
300 365 "--version",
366 "dfu-util",
367 -1,
368 )
369
301 # 10. do the jedi related entries 370 # 10. do the jedi related entries
302 try: 371 try:
303 import jedi 372 import jedi
373
304 try: 374 try:
305 text = os.path.dirname(jedi.__file__) 375 text = os.path.dirname(jedi.__file__)
306 except AttributeError: 376 except AttributeError:
307 text = "jedi" 377 text = "jedi"
308 try: 378 try:
310 except AttributeError: 380 except AttributeError:
311 version = self.tr("(unknown)") 381 version = self.tr("(unknown)")
312 except (ImportError, AttributeError, OSError): 382 except (ImportError, AttributeError, OSError):
313 text = "jedi" 383 text = "jedi"
314 version = "" 384 version = ""
315 self.__createEntry( 385 self.__createEntry(self.tr("Code Assistant - Jedi"), text, version)
316 self.tr("Code Assistant - Jedi"), text, version) 386
317
318 # 11. do the plugin related programs 387 # 11. do the plugin related programs
319 pm = ericApp().getObject("PluginManager") 388 pm = ericApp().getObject("PluginManager")
320 for info in pm.getPluginExeDisplayData(): 389 for info in pm.getPluginExeDisplayData():
321 if info["programEntry"]: 390 if info["programEntry"]:
322 if "exeModule" not in info: 391 if "exeModule" not in info:
333 versionCleanup=info["versionCleanup"], 402 versionCleanup=info["versionCleanup"],
334 versionRe=info["versionRe"], 403 versionRe=info["versionRe"],
335 exeModule=info["exeModule"], 404 exeModule=info["exeModule"],
336 ) 405 )
337 else: 406 else:
338 self.__createEntry( 407 self.__createEntry(info["header"], info["text"], info["version"])
339 info["header"], 408
340 info["text"],
341 info["version"]
342 )
343
344 self.programsList.sortByColumn(0, Qt.SortOrder.AscendingOrder) 409 self.programsList.sortByColumn(0, Qt.SortOrder.AscendingOrder)
345 self.on_showComboBox_currentIndexChanged( 410 self.on_showComboBox_currentIndexChanged(self.showComboBox.currentIndex())
346 self.showComboBox.currentIndex()) 411
347
348 self.__hasSearched = True 412 self.__hasSearched = True
349 413
350 def __createProgramEntry(self, description, exe, 414 def __createProgramEntry(
351 versionCommand="", versionStartsWith="", 415 self,
352 versionPosition=None, version="", 416 description,
353 versionCleanup=None, versionRe=None, 417 exe,
354 exeModule=None): 418 versionCommand="",
419 versionStartsWith="",
420 versionPosition=None,
421 version="",
422 versionCleanup=None,
423 versionRe=None,
424 exeModule=None,
425 ):
355 """ 426 """
356 Private method to generate a program entry. 427 Private method to generate a program entry.
357 428
358 @param description descriptive text (string) 429 @param description descriptive text (string)
359 @param exe name of the executable program (string) 430 @param exe name of the executable program (string)
360 @param versionCommand command line switch to get the version info 431 @param versionCommand command line switch to get the version info
361 (str). If this is empty, the given version will be shown. 432 (str). If this is empty, the given version will be shown.
362 @param versionStartsWith start of line identifying version info 433 @param versionStartsWith start of line identifying version info
372 with the program given in exe (e.g. to execute a Python module) 443 with the program given in exe (e.g. to execute a Python module)
373 (list of str) 444 (list of str)
374 @return version string of detected or given version (string) 445 @return version string of detected or given version (string)
375 """ 446 """
376 itmList = self.programsList.findItems( 447 itmList = self.programsList.findItems(
377 description, Qt.MatchFlag.MatchCaseSensitive) 448 description, Qt.MatchFlag.MatchCaseSensitive
449 )
378 itm = ( 450 itm = (
379 itmList[0] 451 itmList[0] if itmList else QTreeWidgetItem(self.programsList, [description])
380 if itmList else
381 QTreeWidgetItem(self.programsList, [description])
382 ) 452 )
383 font = itm.font(0) 453 font = itm.font(0)
384 font.setBold(True) 454 font.setBold(True)
385 itm.setFont(0, font) 455 itm.setFont(0, font)
386 rememberedExe = exe 456 rememberedExe = exe
395 if exe: 465 if exe:
396 available = True 466 available = True
397 if versionCommand and versionPosition is not None: 467 if versionCommand and versionPosition is not None:
398 proc = QProcess() 468 proc = QProcess()
399 proc.setProcessChannelMode( 469 proc.setProcessChannelMode(
400 QProcess.ProcessChannelMode.MergedChannels) 470 QProcess.ProcessChannelMode.MergedChannels
471 )
401 if exeModule: 472 if exeModule:
402 args = exeModule[:] + [versionCommand] 473 args = exeModule[:] + [versionCommand]
403 else: 474 else:
404 args = [versionCommand] 475 args = [versionCommand]
405 proc.start(exe, args) 476 proc.start(exe, args)
406 finished = proc.waitForFinished(10000) 477 finished = proc.waitForFinished(10000)
407 if finished: 478 if finished:
408 output = str(proc.readAllStandardOutput(), 479 output = str(
409 Preferences.getSystem("IOEncoding"), 480 proc.readAllStandardOutput(),
410 'replace') 481 Preferences.getSystem("IOEncoding"),
482 "replace",
483 )
411 if ( 484 if (
412 exeModule and 485 exeModule
413 exeModule[0] == "-m" and 486 and exeModule[0] == "-m"
414 ("ImportError:" in output or 487 and (
415 "ModuleNotFoundError:" in output or 488 "ImportError:" in output
416 proc.exitCode() != 0) 489 or "ModuleNotFoundError:" in output
490 or proc.exitCode() != 0
491 )
417 ): 492 ):
418 version = self.tr("(module not found)") 493 version = self.tr("(module not found)")
419 available = False 494 available = False
420 elif not versionStartsWith and not versionRe: 495 elif not versionStartsWith and not versionRe:
421 # assume output is just one line 496 # assume output is just one line
422 try: 497 try:
423 version = ( 498 version = output.strip().split()[versionPosition]
424 output.strip().split()[versionPosition]
425 )
426 if versionCleanup: 499 if versionCleanup:
427 version = version[ 500 version = version[
428 versionCleanup[0]: 501 versionCleanup[0] : versionCleanup[1]
429 versionCleanup[1]
430 ] 502 ]
431 except IndexError: 503 except IndexError:
432 version = self.tr("(unknown)") 504 version = self.tr("(unknown)")
433 available = False 505 available = False
434 else: 506 else:
435 if versionRe is None: 507 if versionRe is None:
436 versionRe = "^{0}".format( 508 versionRe = "^{0}".format(re.escape(versionStartsWith))
437 re.escape(versionStartsWith))
438 versionRe = re.compile(versionRe, re.UNICODE) 509 versionRe = re.compile(versionRe, re.UNICODE)
439 for line in output.splitlines(): 510 for line in output.splitlines():
440 if versionRe.search(line): 511 if versionRe.search(line):
441 try: 512 try:
442 version = line.split()[versionPosition] 513 version = line.split()[versionPosition]
443 if versionCleanup: 514 if versionCleanup:
444 version = version[ 515 version = version[
445 versionCleanup[0]: 516 versionCleanup[0] : versionCleanup[1]
446 versionCleanup[1]
447 ] 517 ]
448 break 518 break
449 except IndexError: 519 except IndexError:
450 version = self.tr("(unknown)") 520 version = self.tr("(unknown)")
451 available = False 521 available = False
454 available = False 524 available = False
455 else: 525 else:
456 version = self.tr("(not executable)") 526 version = self.tr("(not executable)")
457 available = False 527 available = False
458 if exeModule: 528 if exeModule:
459 citm = QTreeWidgetItem(itm, [ 529 citm = QTreeWidgetItem(
460 "{0} {1}".format(exe, " ".join(exeModule)), 530 itm, ["{0} {1}".format(exe, " ".join(exeModule)), version]
461 version]) 531 )
462 else: 532 else:
463 citm = QTreeWidgetItem(itm, [exe, version]) 533 citm = QTreeWidgetItem(itm, [exe, version])
464 citm.setData(0, self.ToolAvailableRole, available) 534 citm.setData(0, self.ToolAvailableRole, available)
465 itm.setExpanded(True) 535 itm.setExpanded(True)
466 else: 536 else:
467 if itm.childCount() == 0: 537 if itm.childCount() == 0:
468 itm.setText(1, self.tr("(not found)")) 538 itm.setText(1, self.tr("(not found)"))
469 else: 539 else:
470 citm = QTreeWidgetItem( 540 citm = QTreeWidgetItem(itm, [rememberedExe, self.tr("(not found)")])
471 itm, [rememberedExe, self.tr("(not found)")])
472 citm.setData(0, self.ToolAvailableRole, False) 541 citm.setData(0, self.ToolAvailableRole, False)
473 itm.setExpanded(True) 542 itm.setExpanded(True)
474 QApplication.processEvents() 543 QApplication.processEvents()
475 self.programsList.header().resizeSections( 544 self.programsList.header().resizeSections(
476 QHeaderView.ResizeMode.ResizeToContents) 545 QHeaderView.ResizeMode.ResizeToContents
546 )
477 self.programsList.header().setStretchLastSection(True) 547 self.programsList.header().setStretchLastSection(True)
478 return version 548 return version
479 549
480 def __createEntry(self, description, entryText, entryVersion): 550 def __createEntry(self, description, entryText, entryVersion):
481 """ 551 """
482 Private method to generate a program entry. 552 Private method to generate a program entry.
483 553
484 @param description descriptive text (string) 554 @param description descriptive text (string)
485 @param entryText text to show (string) 555 @param entryText text to show (string)
486 @param entryVersion version string to show (string). 556 @param entryVersion version string to show (string).
487 """ 557 """
488 itm = QTreeWidgetItem(self.programsList, [description]) 558 itm = QTreeWidgetItem(self.programsList, [description])
489 font = itm.font(0) 559 font = itm.font(0)
490 font.setBold(True) 560 font.setBold(True)
491 itm.setFont(0, font) 561 itm.setFont(0, font)
492 562
493 if len(entryVersion): 563 if len(entryVersion):
494 citm = QTreeWidgetItem(itm, [entryText, entryVersion]) 564 citm = QTreeWidgetItem(itm, [entryText, entryVersion])
495 itm.setExpanded(True) 565 itm.setExpanded(True)
496 citm.setData(0, self.ToolAvailableRole, 566 citm.setData(0, self.ToolAvailableRole, not entryVersion.startswith("("))
497 not entryVersion.startswith("("))
498 # assume version starting with '(' is an unavailability 567 # assume version starting with '(' is an unavailability
499 else: 568 else:
500 itm.setText(1, self.tr("(not found)")) 569 itm.setText(1, self.tr("(not found)"))
501 QApplication.processEvents() 570 QApplication.processEvents()
502 self.programsList.header().resizeSections( 571 self.programsList.header().resizeSections(
503 QHeaderView.ResizeMode.ResizeToContents) 572 QHeaderView.ResizeMode.ResizeToContents
573 )
504 self.programsList.header().setStretchLastSection(True) 574 self.programsList.header().setStretchLastSection(True)
505 575
506 @pyqtSlot(int) 576 @pyqtSlot(int)
507 def on_showComboBox_currentIndexChanged(self, index): 577 def on_showComboBox_currentIndexChanged(self, index):
508 """ 578 """
509 Private slot to apply the selected show criteria. 579 Private slot to apply the selected show criteria.
510 580
511 @param index index of the show criterium 581 @param index index of the show criterium
512 @type int 582 @type int
513 """ 583 """
514 if index == 0: 584 if index == 0:
515 # All Supported Tools 585 # All Supported Tools

eric ide

mercurial