diff --git a/constrain/app/__init__.py b/constrain/app/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/constrain/app/app.py b/constrain/app/app.py index ec527013..2cbb93a9 100644 --- a/constrain/app/app.py +++ b/constrain/app/app.py @@ -23,6 +23,7 @@ from .workflow_diagram import WorkflowDiagram from .rect_connect import CustomItem from .submit import Worker, SubmitPopup +from . import utils from constrain.api.workflow import Workflow @@ -148,6 +149,14 @@ def advancedPopupSetting(self): def exportFile(self): """Exports current state as a .json to local storage""" + + scene = self.states_form.scene + if not scene.items(): + utils.send_error( + "Export Error", "Workflow is empty. Add a workflow to export" + ) + return + fp, _ = QFileDialog.getSaveFileName( self, "Save JSON File", "", "JSON Files (*.json);;All Files (*)" ) @@ -162,11 +171,17 @@ def exportFile(self): def exportAsPng(self): """Exports current state as a .png to local storage""" + + scene = self.states_form.scene + if not scene.items(): + utils.send_error( + "Export Error", "Workflow is empty. Add a workflow to export" + ) + return + fp, _ = QFileDialog.getSaveFileName(self, "Save Image", "", "PNG Files (*.png)") if fp: - scene = self.states_form.scene - scene.sceneRect().size() pixmap = QPixmap(scene.sceneRect().size().toSize()) pixmap.fill(QColor(255, 255, 255)) painter = QPainter(pixmap) diff --git a/constrain/app/rect_connect.py b/constrain/app/rect_connect.py index 7f8c4a58..3cf65d59 100644 --- a/constrain/app/rect_connect.py +++ b/constrain/app/rect_connect.py @@ -9,6 +9,8 @@ from PyQt6 import QtCore, QtGui, QtWidgets +from . import utils + class Path(QtWidgets.QGraphicsPathItem): def __init__(self, start, p2, end=None): @@ -241,14 +243,6 @@ def newLineErrorCheck(self, pathItem): if existing.controlPoints() == pathItem.controlPoints(): return False - # define error message - def send_error(text): - error_msg = QtWidgets.QMessageBox() - error_msg.setIcon(QtWidgets.QMessageBox.Icon.Critical) - error_msg.setWindowTitle("Error in Path") - error_msg.setText(text) - error_msg.exec() - # only consider sending error message if self is the start of the path if pathItem.start == self: # determine if parent will have too many children states @@ -256,8 +250,9 @@ def send_error(text): if rect_children_amt >= 1: if self.parent.state["Type"] != "Choice": # MethodCall type CustomItem can only connect to 1 CustomItem - error_msg = "This type cannot connect to more than 1 state" - send_error(error_msg) + utils.send_error( + "Error in Path", "This type cannot connect to more than 1 state" + ) return False elif self.parent.state["Type"] == "Choice": # Choice type CustomItem can connect to more than 1 CustomItem, but need to see how many are defined in the state @@ -267,7 +262,7 @@ def send_error(text): if rect_children_amt >= choices_amt: error_msg = f"This type cannot connect to more than {choices_amt} states" - send_error(error_msg) + utils.send_error("Error in Path", error_msg) return False # add new child node to parent.children since path is viable self.parent.children.append(pathItem.end.parent) diff --git a/constrain/app/utils.py b/constrain/app/utils.py new file mode 100644 index 00000000..49a5524b --- /dev/null +++ b/constrain/app/utils.py @@ -0,0 +1,14 @@ +from PyQt6.QtWidgets import QMessageBox + + +def send_error(window_title, text): + """Displays an error message with given text + + Args: + text (str): text to be displayed + """ + error_msg = QMessageBox() + error_msg.setIcon(QMessageBox.Icon.Critical) + error_msg.setWindowTitle(window_title) + error_msg.setText(text) + error_msg.exec()