From 56e81186398897171021f47ca9b2989c0af8db8a Mon Sep 17 00:00:00 2001 From: Jacob Wahlman <jacwa448@student.liu.se> Date: Tue, 19 May 2020 17:21:16 +0200 Subject: [PATCH] lots of bug fixes in gui --- b_asic/GUI/arrow.py | 11 ++- b_asic/GUI/drag_button.py | 3 +- b_asic/GUI/main_window.py | 69 +++++++++++++++--- b_asic/GUI/operation_icons/{reg.png => t.png} | Bin .../{reg_grey.png => t_grey.png} | Bin b_asic/GUI/properties_window.py | 5 +- b_asic/save_load_structure.py | 5 +- 7 files changed, 78 insertions(+), 15 deletions(-) rename b_asic/GUI/operation_icons/{reg.png => t.png} (100%) rename b_asic/GUI/operation_icons/{reg_grey.png => t_grey.png} (100%) diff --git a/b_asic/GUI/arrow.py b/b_asic/GUI/arrow.py index aea8fec3..eb4e279d 100644 --- a/b_asic/GUI/arrow.py +++ b/b_asic/GUI/arrow.py @@ -30,7 +30,16 @@ class Arrow(QGraphicsLineItem): self.signal.remove_destination() self.signal.remove_source() self._window.scene.removeItem(self) - self._window.signalList.remove(self) + if self in self._window.signalList: + self._window.signalList.remove(self) + + if self in self._window.signalPortDict: + for port1, port2 in self._window.signalPortDict[self]: + for operation, operation_ports in self._window.portDict.items(): + if (port1 in operation_ports or port2 in operation_ports) and operation in self._window.opToSFG: + self._window.logger.info(f"Operation detected in existing sfg, removing sfg with name: {self._window.opToSFG[operation].name}.") + del self._window.sfg_dict[self._window.opToSFG[operation].name] + self._window.opToSFG = {op: self._window.opToSFG[op] for op in self._window.opToSFG if self._window.opToSFG[op] is not self._window.opToSFG[operation]} def moveLine(self): self.setPen(QPen(Qt.black, 3)) diff --git a/b_asic/GUI/drag_button.py b/b_asic/GUI/drag_button.py index fe78f463..a67027d8 100644 --- a/b_asic/GUI/drag_button.py +++ b/b_asic/GUI/drag_button.py @@ -128,11 +128,12 @@ class DragButton(QPushButton): if self in self._window.opToSFG: self._window.logger.info(f"Operation detected in existing sfg, removing sfg with name: {self._window.opToSFG[self].name}.") - self._window.opToSFG = {op: self._window.opToSFG[op] for op in self._window.opToSFG if self._window.opToSFG[op] is self._window.opToSFG[self]} del self._window.sfg_dict[self._window.opToSFG[self].name] + self._window.opToSFG = {op: self._window.opToSFG[op] for op in self._window.opToSFG if self._window.opToSFG[op] is not self._window.opToSFG[self]} for signal in _signals: del self._window.signalPortDict[signal] + signal.remove() for port in self._window.portDict[self]: if port in self._window.pressed_ports: diff --git a/b_asic/GUI/main_window.py b/b_asic/GUI/main_window.py index 0607100a..9f232ad8 100644 --- a/b_asic/GUI/main_window.py +++ b/b_asic/GUI/main_window.py @@ -101,6 +101,8 @@ class MainWindow(QMainWindow): self.shortcut_save.activated.connect(self.save_work) self.shortcut_help = QShortcut(QKeySequence("Ctrl+?"), self) self.shortcut_help.activated.connect(self.display_faq_page) + self.shortcut_signal = QShortcut(QKeySequence(Qt.Key_Space), self) + self.shortcut_signal.activated.connect(self._connect_button) self.logger.info("Finished setting up GUI") self.logger.info("For questions please refer to 'Ctrl+?', or visit the 'Help' section on the toolbar.") @@ -257,11 +259,56 @@ class MainWindow(QMainWindow): sfg = SFG(inputs=inputs, outputs=outputs, name=name) self.logger.info(f"Created SFG with name: {name} from selected operations.") - sfg_operations = sfg.operations.copy() - for op in self.pressed_operations: - operation = [op_ for op_ in sfg_operations if op_.type_name() == op.operation.type_name()][0] - op.operation = operation - sfg_operations.remove(operation) + def check_equality(signal, signal_2): + # check operation types + if not (signal.source.operation.type_name() == signal_2.source.operation.type_name() \ + and signal.destination.operation.type_name() == signal_2.destination.operation.type_name()): + return False + + if hasattr(signal.source.operation, "value") and hasattr(signal_2.source.operation, "value") \ + and hasattr(signal.destination.operation, "value") and hasattr(signal_2.destination.operation, "value"): + if not (signal.source.operation.value == signal_2.source.operation.value \ + and signal.destination.operation.value == signal_2.destination.operation.value): + return False + + if hasattr(signal.source.operation, "name") and hasattr(signal_2.source.operation, "name") \ + and hasattr(signal.destination.operation, "name") and hasattr(signal_2.destination.operation, "name"): + if not (signal.source.operation.name == signal_2.source.operation.name \ + and signal.destination.operation.name == signal_2.destination.operation.name): + return False + + try: + _signal_source_index = [signal.source.operation.outputs.index(port) for port in signal.source.operation.outputs if signal in port.signals] + _signal_2_source_index = [signal_2.source.operation.outputs.index(port) for port in signal_2.source.operation.outputs if signal_2 in port.signals] + except ValueError: + return False # Signal output connections not matching + + try: + _signal_destination_index = [signal.destination.operation.inputs.index(port) for port in signal.destination.operation.inputs if signal in port.signals] + _signal_2_destination_index = [signal_2.destination.operation.inputs.index(port) for port in signal_2.destination.operation.inputs if signal_2 in port.signals] + except ValueError: + return False # Signal input connections not matching + + if not (_signal_source_index == _signal_2_source_index and _signal_destination_index == _signal_2_destination_index): + return False + + return True + + for pressed_op in self.pressed_operations: + for operation in sfg.operations: + for input_ in operation.inputs: + for signal in input_.signals: + for line in self.signalPortDict: + if check_equality(line.signal, signal): + line.source.operation.operation = signal.source.operation + line.destination.operation.operation = signal.destination.operation + + for output_ in operation.outputs: + for signal in output_.signals: + for line in self.signalPortDict: + if check_equality(line.signal, signal): + line.source.operation.operation = signal.source.operation + line.destination.operation.operation = signal.destination.operation for op in self.pressed_operations: op.setToolTip(sfg.name) @@ -352,10 +399,9 @@ class MainWindow(QMainWindow): attr_button.setParent(None) attr_button_scene = self.scene.addWidget(attr_button) if position is None: - attr_button_scene.moveBy(self.move_button_index * 100, 0) + attr_button_scene.moveBy(int(self.scene.width() / 2), int(self.scene.height() / 2)) attr_button_scene.setFlag(attr_button_scene.ItemIsSelectable, True) - self.move_button_index += 1 - operation_label = QGraphicsTextItem(op.type_name(), attr_button_scene) + operation_label = QGraphicsTextItem(op.name, attr_button_scene) if not self.is_show_names: operation_label.setOpacity(0) operation_label.setTransformOriginPoint(operation_label.boundingRect().center()) @@ -394,7 +440,7 @@ class MainWindow(QMainWindow): self.pressed_operations.clear() super().keyPressEvent(event) - def _connect_button(self, event): + def _connect_button(self, *event): if len(self.pressed_ports) < 2: self.logger.warning("Can't connect less than two ports. Please select more.") return @@ -403,6 +449,11 @@ class MainWindow(QMainWindow): source = self.pressed_ports[i] if isinstance(self.pressed_ports[i].port, OutputPort) else self.pressed_ports[i + 1] destination = self.pressed_ports[i + 1] if source is not self.pressed_ports[i + 1] else self.pressed_ports[i] if source.port.operation is destination.port.operation: + self.logger.warning("Can't connect to the same port") + continue + + if type(source.port) == type(destination.port): + self.logger.warning(f"Can't connect port of type: {type(source.port).__name__} to port of type: {type(destination.port).__name__}.") continue self.connect_button(source, destination) diff --git a/b_asic/GUI/operation_icons/reg.png b/b_asic/GUI/operation_icons/t.png similarity index 100% rename from b_asic/GUI/operation_icons/reg.png rename to b_asic/GUI/operation_icons/t.png diff --git a/b_asic/GUI/operation_icons/reg_grey.png b/b_asic/GUI/operation_icons/t_grey.png similarity index 100% rename from b_asic/GUI/operation_icons/reg_grey.png rename to b_asic/GUI/operation_icons/t_grey.png diff --git a/b_asic/GUI/properties_window.py b/b_asic/GUI/properties_window.py index 04d899fd..af6cf762 100644 --- a/b_asic/GUI/properties_window.py +++ b/b_asic/GUI/properties_window.py @@ -22,7 +22,7 @@ class PropertiesWindow(QDialog): self.vertical_layout = QVBoxLayout() self.vertical_layout.addLayout(self.name_layout) - if self.operation.operation_path_name == "c": + if hasattr(self.operation.operation, "value"): self.constant_layout = QHBoxLayout() self.constant_layout.setSpacing(50) self.constant_value = QLabel("Constant:") @@ -122,8 +122,9 @@ class PropertiesWindow(QDialog): def save_properties(self): self._window.logger.info(f"Saving properties of operation: {self.operation.name}.") self.operation.name = self.edit_name.text() + self.operation.operation.name = self.edit_name.text() self.operation.label.setPlainText(self.operation.name) - if self.operation.operation_path_name == "c": + if hasattr(self.operation.operation, "value"): self.operation.operation.value = int(self.edit_constant.text()) if self.check_show_name.isChecked(): self.operation.label.setOpacity(1) diff --git a/b_asic/save_load_structure.py b/b_asic/save_load_structure.py index 5311d3fe..88e1d4fb 100644 --- a/b_asic/save_load_structure.py +++ b/b_asic/save_load_structure.py @@ -62,8 +62,9 @@ def sfg_to_python(sfg: SFG, counter: int = 0, suffix: str = None) -> str: inputs = "[" + ", ".join(op.graph_id for op in sfg.input_operations) + "]" outputs = "[" + ", ".join(op.graph_id for op in sfg.output_operations) + "]" sfg_name = sfg.name if sfg.name else "sfg" + str(counter) if counter > 0 else 'sfg' - result += f"\n{sfg_name} = SFG(inputs={inputs}, outputs={outputs}, name='{sfg_name}')\n" - result += "\n# SFG Properties:\n" + "prop = {'name':" + f"{sfg_name}" + "}" + sfg_name_var = sfg_name.replace(" ", "_") + result += f"\n{sfg_name_var} = SFG(inputs={inputs}, outputs={outputs}, name='{sfg_name}')\n" + result += "\n# SFG Properties:\n" + "prop = {'name':" + f"{sfg_name_var}" + "}" if suffix is not None: result += "\n" + suffix + "\n" -- GitLab