class ArrayRequirementEditor: def __init__(self, parent: QWidget, parent_layout: QVBoxLayout, line_layout: QHBoxLayout, resource_database: ResourceDatabase, requirement: RequirementArrayBase): self._editors = [] self.resource_database = resource_database self._array_type = type(requirement) # the parent is added to a layout which is added to parent_layout, so we index = parent_layout.indexOf(line_layout) + 1 self.group_box = QGroupBox(parent) self.group_box.setStyleSheet("QGroupBox { margin-top: 2px; }") parent_layout.insertWidget(index, self.group_box) self.item_layout = QVBoxLayout(self.group_box) self.item_layout.setContentsMargins(8, 2, 2, 6) self.item_layout.setAlignment(Qt.AlignTop) self.new_item_button = QPushButton(self.group_box) self.new_item_button.setMaximumWidth(75) self.new_item_button.setText("New Row") self.new_item_button.clicked.connect(self.new_item) self.comment_text_box = QLineEdit(parent) self.comment_text_box.setText(requirement.comment or "") self.comment_text_box.setPlaceholderText("Comment") line_layout.addWidget(self.comment_text_box) for item in requirement.items: self._create_item(item) self.item_layout.addWidget(self.new_item_button) def _create_item(self, item: Requirement): def on_remove(): self._editors.remove(nested_editor) nested_editor.deleteLater() nested_editor = RequirementEditor(self.group_box, self.item_layout, self.resource_database, on_remove=on_remove) nested_editor.create_specialized_editor(item) self._editors.append(nested_editor) def new_item(self): self._create_item( _create_default_resource_requirement(self.resource_database)) self.item_layout.removeWidget(self.new_item_button) self.item_layout.addWidget(self.new_item_button) def deleteLater(self): self.group_box.deleteLater() self.comment_text_box.deleteLater() for editor in self._editors: editor.deleteLater() self.new_item_button.deleteLater() @property def current_requirement(self) -> RequirementArrayBase: comment = self.comment_text_box.text().strip() if comment == "": comment = None return self._array_type( [editor.current_requirement for editor in self._editors], comment=comment, )
class ItemRow: def __init__(self, parent: QWidget, parent_layout: QVBoxLayout, resource_database: ResourceDatabase, item: ResourceRequirement, rows: List["ItemRow"]): self.parent = parent self.resource_database = resource_database self._rows = rows rows.append(self) self.layout = QHBoxLayout() self.layout.setObjectName(f"Box layout for {item.resource.long_name}") parent_layout.addLayout(self.layout) self.resource_type_combo = _create_resource_type_combo( item.resource.resource_type, parent) self.resource_type_combo.setMinimumWidth(75) self.resource_type_combo.setMaximumWidth(75) self.resource_name_combo = _create_resource_name_combo( self.resource_database, item.resource.resource_type, item.resource, self.parent) self.negate_combo = QComboBox(parent) self.negate_combo.addItem("≥", False) self.negate_combo.addItem("<", True) self.negate_combo.setCurrentIndex(int(item.negate)) self.negate_combo.setMinimumWidth(40) self.negate_combo.setMaximumWidth(40) self.amount_edit = QLineEdit(parent) self.amount_edit.setValidator(QIntValidator(1, 10000)) self.amount_edit.setText(str(item.amount)) self.amount_edit.setMinimumWidth(45) self.amount_edit.setMaximumWidth(45) self.remove_button = QPushButton(parent) self.remove_button.setText("X") self.remove_button.setMaximumWidth(20) self.layout.addWidget(self.resource_type_combo) self.layout.addWidget(self.resource_name_combo) self.layout.addWidget(self.negate_combo) self.layout.addWidget(self.amount_edit) self.layout.addWidget(self.remove_button) self.resource_type_combo.currentIndexChanged.connect(self._update_type) self.remove_button.clicked.connect(self._delete_row) def _update_type(self): old_combo = self.resource_name_combo self.resource_name_combo = _create_resource_name_combo( self.resource_database, self.resource_type_combo.currentData(), None, self.parent) self.layout.replaceWidget(old_combo, self.resource_name_combo) old_combo.deleteLater() def _delete_row(self): self.resource_type_combo.deleteLater() self.resource_name_combo.deleteLater() self.negate_combo.deleteLater() self.amount_edit.deleteLater() self.remove_button.deleteLater() self.layout.deleteLater() self._rows.remove(self) @property def current_individual(self) -> ResourceRequirement: return ResourceRequirement(self.resource_name_combo.currentData(), int(self.amount_edit.text()), self.negate_combo.currentData())