--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/eric7/CycloneDXInterface/CycloneDXMetaDataDialog.py Thu Jul 07 11:23:56 2022 +0200 @@ -0,0 +1,128 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2022 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to edit the metadata of the CycloneDX SBOM. +""" + +from PyQt6.QtCore import pyqtSlot, QCoreApplication +from PyQt6.QtWidgets import QDialog, QDialogButtonBox + +from cyclonedx.model.component import ComponentType +import trove_classifiers + +from .Ui_CycloneDXMetaDataDialog import Ui_CycloneDXMetaDataDialog + + +class CycloneDXMetaDataDialog(QDialog, Ui_CycloneDXMetaDataDialog): + """ + Class implementing a dialog to edit the metadata of the CycloneDX SBOM. + """ + ComponentTypeMapping = { + ComponentType.APPLICATION: QCoreApplication.translate( + "CycloneDXMetaDataDialog", "Application"), + ComponentType.CONTAINER: QCoreApplication.translate( + "CycloneDXMetaDataDialog", "Container"), + ComponentType.DEVICE: QCoreApplication.translate( + "CycloneDXMetaDataDialog", "Device"), + ComponentType.FILE: QCoreApplication.translate( + "CycloneDXMetaDataDialog", "File"), + ComponentType.FIRMWARE: QCoreApplication.translate( + "CycloneDXMetaDataDialog", "Firmware"), + ComponentType.FRAMEWORK: QCoreApplication.translate( + "CycloneDXMetaDataDialog", "Framework"), + ComponentType.LIBRARY: QCoreApplication.translate( + "CycloneDXMetaDataDialog", "Library"), + ComponentType.OPERATING_SYSTEM: QCoreApplication.translate( + "CycloneDXMetaDataDialog", "Operating System"), + } + + def __init__(self, metadata=None, parent=None): + """ + Constructor + + @param metadata dictionary containing metadata to populate the dialog + (defaults to None) + @type dict (optional) + @param parent reference to the parent widget (defaults to None) + @type QWidget (optional) + """ + super().__init__(parent) + self.setupUi(self) + + self.__populateComponentTypeSelector() + self.__populateLicenseSelector() + + if metadata: + # populate the dialog from given metadata dictionary + self.nameEdit.setText(metadata["Name"]) + self.versionEdit.setText(metadata["Version"]) + self.descriptionEdit.setPlainText(metadata["Description"]) + self.authorEdit.setText(metadata["AuthorName"]) + self.emailEdit.setText(metadata["AuthorEmail"]) + self.licenseComboBox.setCurrentText(metadata["License"]) + self.manufacturerEdit.setText(metadata["Manufacturer"]) + self.supplierEdit.setText(metadata["Supplier"]) + index = self.typeComboBox.findData(metadata["Type"]) + self.typeComboBox.setCurrentIndex(index) + + self.nameEdit.textChanged.connect(self.__updateOkButton) + self.typeComboBox.currentTextChanged.connect(self.__updateOkButton) + self.licenseComboBox.currentTextChanged.connect(self.__updateOkButton) + + self.__updateOkButton() + + def __populateComponentTypeSelector(self): + """ + Private method to populate the component type selector. + """ + self.typeComboBox.addItem("", "") + for componentType, displayStr in sorted( + CycloneDXMetaDataDialog.ComponentTypeMapping.items(), + key=lambda x: x[1] + ): + self.typeComboBox.addItem(displayStr, componentType) + + def __populateLicenseSelector(self): + """ + Private method to populate the license selector with the list of trove + license types. + """ + self.licenseComboBox.addItem("") + self.licenseComboBox.addItems(sorted( + classifier.split("::")[-1].strip() + for classifier in trove_classifiers.classifiers + if classifier.startswith("License ::") + )) + + @pyqtSlot() + def __updateOkButton(self): + """ + Private slot to update the enabled state of the OK button. + """ + self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled( + bool(self.nameEdit.text()) and + bool(self.typeComboBox.currentText()) and + bool(self.licenseComboBox.currentText()) + ) + + def getMetaData(self): + """ + Public method to get the entered data. + + @return dictionary containing the metadata. + @rtype dict + """ + return { + "Name": self.nameEdit.text(), + "Type": self.typeComboBox.currentData(), + "Version": self.versionEdit.text(), + "Description": self.descriptionEdit.toPlainText(), + "AuthorName": self.authorEdit.text(), + "AuthorEmail": self.emailEdit.text(), + "License": self.licenseComboBox.currentText(), + "Manufacturer": self.manufacturerEdit.text(), + "Supplier": self.supplierEdit.text(), + }