28 |
28 |
29 class ProgramsDialog(QDialog, Ui_ProgramsDialog): |
29 class ProgramsDialog(QDialog, Ui_ProgramsDialog): |
30 """ |
30 """ |
31 Class implementing the Programs page. |
31 Class implementing the Programs page. |
32 """ |
32 """ |
|
33 ToolAvailableRole = Qt.UserRole + 1 |
|
34 |
33 def __init__(self, parent=None): |
35 def __init__(self, parent=None): |
34 """ |
36 """ |
35 Constructor |
37 Constructor |
36 |
38 |
37 @param parent The parent widget of this dialog. (QWidget) |
39 @param parent The parent widget of this dialog. (QWidget) |
332 info["text"], |
334 info["text"], |
333 info["version"] |
335 info["version"] |
334 ) |
336 ) |
335 |
337 |
336 self.programsList.sortByColumn(0, Qt.AscendingOrder) |
338 self.programsList.sortByColumn(0, Qt.AscendingOrder) |
|
339 self.on_showUnavailableCheckBox_toggled( |
|
340 self.showUnavailableCheckBox.isChecked()) |
337 QApplication.restoreOverrideCursor() |
341 QApplication.restoreOverrideCursor() |
338 |
342 |
339 self.__hasSearched = True |
343 self.__hasSearched = True |
340 |
344 |
341 def __createProgramEntry(self, description, exe, |
345 def __createProgramEntry(self, description, exe, |
372 itm = QTreeWidgetItem(self.programsList, [description]) |
376 itm = QTreeWidgetItem(self.programsList, [description]) |
373 font = itm.font(0) |
377 font = itm.font(0) |
374 font.setBold(True) |
378 font.setBold(True) |
375 itm.setFont(0, font) |
379 itm.setFont(0, font) |
376 rememberedExe = exe |
380 rememberedExe = exe |
|
381 available = True |
377 if not exe: |
382 if not exe: |
378 itm.setText(1, self.tr("(not configured)")) |
383 itm.setText(1, self.tr("(not configured)")) |
379 else: |
384 else: |
380 if os.path.isabs(exe): |
385 if os.path.isabs(exe): |
381 if not Utilities.isExecutable(exe): |
386 if not Utilities.isExecutable(exe): |
407 ("ImportError:" in output or |
412 ("ImportError:" in output or |
408 "ModuleNotFoundError:" in output or |
413 "ModuleNotFoundError:" in output or |
409 proc.exitCode() != 0) |
414 proc.exitCode() != 0) |
410 ): |
415 ): |
411 version = self.tr("(module not found)") |
416 version = self.tr("(module not found)") |
|
417 available = False |
412 else: |
418 else: |
413 if versionRe is None: |
419 if versionRe is None: |
414 versionRe = "^{0}".format( |
420 versionRe = "^{0}".format( |
415 re.escape(versionStartsWith)) |
421 re.escape(versionStartsWith)) |
416 versionRe = re.compile(versionRe, re.UNICODE) |
422 versionRe = re.compile(versionRe, re.UNICODE) |
424 versionCleanup[1] |
430 versionCleanup[1] |
425 ] |
431 ] |
426 break |
432 break |
427 except IndexError: |
433 except IndexError: |
428 version = self.tr("(unknown)") |
434 version = self.tr("(unknown)") |
|
435 available = False |
429 else: |
436 else: |
430 version = self.tr("(unknown)") |
437 version = self.tr("(unknown)") |
|
438 available = False |
431 else: |
439 else: |
432 version = self.tr("(not executable)") |
440 version = self.tr("(not executable)") |
|
441 available = False |
433 if exeModule: |
442 if exeModule: |
434 QTreeWidgetItem(itm, [ |
443 QTreeWidgetItem(itm, [ |
435 "{0} {1}".format(exe, " ".join(exeModule)), |
444 "{0} {1}".format(exe, " ".join(exeModule)), |
436 version]) |
445 version]) |
437 else: |
446 else: |
442 itm.setText(1, self.tr("(not found)")) |
451 itm.setText(1, self.tr("(not found)")) |
443 else: |
452 else: |
444 QTreeWidgetItem(itm, [rememberedExe, |
453 QTreeWidgetItem(itm, [rememberedExe, |
445 self.tr("(not found)")]) |
454 self.tr("(not found)")]) |
446 itm.setExpanded(True) |
455 itm.setExpanded(True) |
|
456 available = False |
|
457 itm.setData(0, self.ToolAvailableRole, available) |
447 QApplication.processEvents() |
458 QApplication.processEvents() |
448 self.programsList.header().resizeSections(QHeaderView.ResizeToContents) |
459 self.programsList.header().resizeSections(QHeaderView.ResizeToContents) |
449 self.programsList.header().setStretchLastSection(True) |
460 self.programsList.header().setStretchLastSection(True) |
450 return version |
461 return version |
451 |
462 |
459 """ |
470 """ |
460 itm = QTreeWidgetItem(self.programsList, [description]) |
471 itm = QTreeWidgetItem(self.programsList, [description]) |
461 font = itm.font(0) |
472 font = itm.font(0) |
462 font.setBold(True) |
473 font.setBold(True) |
463 itm.setFont(0, font) |
474 itm.setFont(0, font) |
|
475 available = True |
464 |
476 |
465 if len(entryVersion): |
477 if len(entryVersion): |
466 QTreeWidgetItem(itm, [entryText, entryVersion]) |
478 QTreeWidgetItem(itm, [entryText, entryVersion]) |
467 itm.setExpanded(True) |
479 itm.setExpanded(True) |
|
480 if entryVersion.startswith("("): |
|
481 # assume version starting with '(' is an unavailability |
|
482 # indicator |
|
483 available = False |
468 else: |
484 else: |
469 itm.setText(1, self.tr("(not found)")) |
485 itm.setText(1, self.tr("(not found)")) |
|
486 available = False |
|
487 itm.setData(0, self.ToolAvailableRole, available) |
470 QApplication.processEvents() |
488 QApplication.processEvents() |
471 self.programsList.header().resizeSections(QHeaderView.ResizeToContents) |
489 self.programsList.header().resizeSections(QHeaderView.ResizeToContents) |
472 self.programsList.header().setStretchLastSection(True) |
490 self.programsList.header().setStretchLastSection(True) |
|
491 |
|
492 @pyqtSlot(bool) |
|
493 def on_showUnavailableCheckBox_toggled(self, checked): |
|
494 """ |
|
495 Private slot show or hide entries belonging to unavailable but |
|
496 supported tools. |
|
497 |
|
498 @param checked state of the check box |
|
499 @type bool |
|
500 """ |
|
501 for index in range(self.programsList.topLevelItemCount()): |
|
502 itm = self.programsList.topLevelItem(index) |
|
503 itm.setHidden(not checked and |
|
504 not itm.data(0, self.ToolAvailableRole)) |
|
505 # TODO: change filter to a selection combo with |
|
506 # All Supported Tools |
|
507 # Found Tools Only |
|
508 # Unavailable Tools Only |
|
509 # TODO: add available flag to each child item and derive parent status from |
|
510 # them |