summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/python/main.py20
-rw-r--r--src/main/python/shapes/shapes.py41
-rw-r--r--src/main/python/utils/graphics.py109
-rw-r--r--src/main/resources/base/config/items.json4
4 files changed, 154 insertions, 20 deletions
diff --git a/src/main/python/main.py b/src/main/python/main.py
index 5af252d..de8a12b 100644
--- a/src/main/python/main.py
+++ b/src/main/python/main.py
@@ -26,7 +26,10 @@ class appWindow(QMainWindow):
#create the menu bar
self.createMenuBar()
-
+
+ #used for file name
+ self.counterr = 0
+
self.mdi = QMdiArea(self) #create area for files to be displayed
self.mdi.setObjectName('mdi area')
@@ -139,8 +142,19 @@ class appWindow(QMainWindow):
return True
def saveImage(self):
- #place holder for future implementaion
- pass
+ #save the scene as png or jpg
+ if self.mdi.currentSubWindow():
+ currentDiagram = self.mdi.currentSubWindow().tabber.currentWidget().painter
+ if currentDiagram:
+ name = QFileDialog.getSaveFileName(self, 'Save File', f'New Image {self.counterr}', 'PNG (*.png);;JPEG (*.jpg)')
+ if name[0]:
+ image = QImage(currentDiagram.sceneRect().size().toSize(), QImage.Format_ARGB32)
+ image.fill(Qt.transparent)
+ painter = QPainter(image)
+ currentDiagram.render(painter)
+ image.save(name[0])
+ self.counterr += 1
+ painter.end()
def generateReport(self):
#place holder for future implementaion
diff --git a/src/main/python/shapes/shapes.py b/src/main/python/shapes/shapes.py
index a67e8dc..55d1751 100644
--- a/src/main/python/shapes/shapes.py
+++ b/src/main/python/shapes/shapes.py
@@ -767,7 +767,7 @@ class NodeItem(QGraphicsSvgItem):
class InflowLine(NodeItem):
def __init__(self):
- super(InflowLine, self).__init__("svg/piping/Inflow Line")
+ super(InflowLine, self).__init__("svg/Piping/Inflow Line")
self.grips = [
[100, 50, "right"]
]
@@ -931,14 +931,34 @@ class SolidFuelFurnace(NodeItem):
]
+class Exchanger905(NodeItem):
+ def __init__(self):
+ super(Exchanger905, self).__init__("svg/Heating or Cooling Arrangements/905Exchanger")
+ self.grips = [
+ [15.85, 13.5, "bottom", 11.21],
+ [60.5, 13.5, "bottom", 55.33],
+ [15.85, 88.88, "top", 11.21],
+ [60.5, 88.88, "top", 55.33]
+ ]
+
+class KettleReboiler907(NodeItem):
+ def __init__(self):
+ super(KettleReboiler907, self).__init__("svg/Heating or Cooling Arrangements/907Kettle Reboiler")
+ self.grips = [
+ [18, 20.33, "bottom", 18],
+ [70, 20.33, "bottom", 40.33],
+ [18, 75, "top", 18],
+ [70, 96, "top", 40.33]
+ ]
+
class Exchanger(NodeItem):
def __init__(self):
super(Exchanger, self).__init__("svg/Heating or Cooling Arrangements/Exchanger")
self.grips = [
[100, 31.74474612706027, "right"],
[100, 62.70549343934227, "right"],
- [33.68240920045628, 100, "top"],
- [33.68240920045628, 0, "bottom"]
+ [35.66, 100, "top"],
+ [36.66, 0, "bottom"]
]
@@ -961,6 +981,15 @@ class ImmersionCoil(NodeItem):
[88.232463407718, 100, "top"]
]
+class KettleReboiler(NodeItem):
+ def __init__(self):
+ super(KettleReboiler, self).__init__("svg/Heating or Cooling Arrangements/Kettle Reboiler")
+ self.grips = [
+ [100, 26.3, "right"],
+ [0, 26.3, "left"],
+ [50, 100, "top"],
+ [50, 0, "bottom"]
+ ]
class HorizontalVessel(NodeItem):
def __init__(self):
@@ -1066,11 +1095,11 @@ class OneCellFiredHeaterFurnace(NodeItem):
super(OneCellFiredHeaterFurnace, self).__init__("svg/Furnaces and Boilers/One Cell Fired Heater, Furnace")
self.grips = [
[50, 100, "top"],
- [0-7, 25, "left", 50],
+ [0, 28, "left", 45],
[25, 87.5, "left", 25],
- [100+7, 25, "right", 50],
+ [100, 28, "right", 45],
[75, 87.5, "right", 25],
- [50, 0-10, "bottom", 100]
+ [50, 0-5, "bottom", 100]
]
diff --git a/src/main/python/utils/graphics.py b/src/main/python/utils/graphics.py
index 80eb5e7..a4b3916 100644
--- a/src/main/python/utils/graphics.py
+++ b/src/main/python/utils/graphics.py
@@ -1,4 +1,7 @@
+from PyQt5 import QtCore, QtGui, QtWidgets
+from PyQt5.QtCore import Qt, QRectF, QPointF
from PyQt5.QtCore import Qt, QPointF, pyqtSignal
+from PyQt5.QtWidgets import QGraphicsScene, QApplication
from PyQt5.QtGui import QPen, QKeySequence, QTransform, QCursor
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QGraphicsProxyWidget, QGraphicsItem, QUndoStack, QAction, QUndoView
@@ -73,16 +76,18 @@ class CustomView(QGraphicsView):
temp = self.zoom
self._zoom = value
self.scale(self.zoom / temp, self.zoom / temp)
-
+
class CustomScene(QGraphicsScene):
"""
Extends QGraphicsScene with undo-redo functionality
"""
labelAdded = pyqtSignal(shapes.QGraphicsItem)
-
+ itemMoved = QtCore.pyqtSignal(QtWidgets.QGraphicsItem, QtCore.QPointF)
+
def __init__(self, *args, parent=None):
super(CustomScene, self).__init__(*args, parent=parent)
-
+ self.movingItems = [] # List to store selected items for moving
+ self.oldPositions = {} # Dictionary to store old positions of moved items
self.undoStack = QUndoStack(self) #Used to store undo-redo moves
self.createActions() #creates necessary actions that need to be called for undo-redo
@@ -91,12 +96,12 @@ class CustomScene(QGraphicsScene):
self.deleteAction = QAction("Delete Item", self)
self.deleteAction.setShortcut(Qt.Key_Delete)
self.deleteAction.triggered.connect(self.deleteItem)
-
+
self.undoAction = self.undoStack.createUndoAction(self, "Undo")
self.undoAction.setShortcut(QKeySequence.Undo)
self.redoAction = self.undoStack.createRedoAction(self, "Redo")
self.redoAction.setShortcut(QKeySequence.Redo)
-
+
def createUndoView(self, parent):
# creates an undo stack view for current QGraphicsScene
undoView = QUndoView(self.undoStack, parent)
@@ -115,17 +120,101 @@ class CustomScene(QGraphicsScene):
self.count+=1
self.undoStack.push(deleteCommand(j, self))
self.undoStack.push(deleteCommand(itemToDelete, self))
-
+
def itemMoved(self, movedItem, lastPos):
#item move event, checks if item is moved
self.undoStack.push(moveCommand(movedItem, lastPos))
self.advance()
-
+
def addItemPlus(self, item):
# extended add item method, so that a corresponding undo action is also pushed
self.undoStack.push(addCommand(item, self))
-
+
def mousePressEvent(self, event):
+ bdsp = event.buttonDownScenePos(Qt.LeftButton) # Get click position
+ point = QPointF(bdsp.x(), bdsp.y()) # Create a QPointF from click position
+ itemList = self.items(point) # Get items at the specified point
+ if itemList:
+ item = itemList[0] # Select the first item in the list
+ if event.button() == Qt.LeftButton:
+ modifiers = QApplication.keyboardModifiers()
+ if modifiers == Qt.ControlModifier:
+ # Ctrl key is pressed, add item to the moving items list
+ if item not in self.movingItems:
+ self.movingItems.append(item)
+ self.oldPositions[item] = item.pos()
+ else:
+ # Ctrl key is not pressed, clear the moving items list and selection
+ self.movingItems.clear()
+ self.clearSelection()
+ item.setSelected(True)
+
+ return super(CustomScene, self).mousePressEvent(event)
+
+
+ def mouseReleaseEvent(self, event):
+ if event.button() == QtCore.Qt.LeftButton:
+ for item in self.movingItems:
+ if self.oldPositions[item] != item.pos():
+ # Item position has changed, invoke the callback function
+ self.itemMoved(item, self.oldPositions[item])
+ self.movingItems.clear() # Clear the moving items list
+ self.oldPositions.clear() # Clear the old positions dictionary
+
+ return super(CustomScene, self).mouseReleaseEvent(event)
+
+
+ def mouseMoveEvent(self, mouseEvent):
+ if self.movingItems:
+ # Move all selected items together
+ for item in self.movingItems:
+ newPos = item.pos() + mouseEvent.scenePos() - mouseEvent.lastScenePos()
+ item.setPos(newPos)
+
+ item = self.itemAt(mouseEvent.scenePos().x(), mouseEvent.scenePos().y(), QTransform())
+ if isinstance(item, shapes.SizeGripItem):
+ item.parentItem().showLineGripItem()
+
+ return super(CustomScene, self).mouseMoveEvent(mouseEvent)
+
+ # The above is the mouse events for moving multiple images at once.
+
+ """def mousePressEvent(self, event):
+ bdsp = event.buttonDownScenePos(Qt.LeftButton) # get click pos
+ point = QPointF(bdsp.x(), bdsp.y()) # create a QPointF from click pos
+ itemList = self.items(point) # get items at said point
+ if event.button() == Qt.LeftButton:
+ if itemList:
+ self.movingItems = itemList
+ self.initialPositions = {}
+ for item in self.movingItems:
+ self.initialPositions[item] = item.pos()
+ else:
+ self.movingItems = []
+ self.clearSelection()
+ return super(CustomScene, self).mousePressEvent(event)
+
+ def mouseMoveEvent(self, event):
+ if event.buttons() == Qt.LeftButton and self.movingItems:
+ modifiers = QApplication.keyboardModifiers()
+ if modifiers == Qt.ControlModifier:
+ for item in self.movingItems:
+ item.setPos(item.pos() + event.scenePos() - event.lastScenePos())
+ else:
+ super(CustomScene, self).mouseMoveEvent(event)
+
+ def mouseReleaseEvent(self, event):
+ if event.button() == Qt.LeftButton and self.movingItems:
+ for item in self.movingItems:
+ if item.pos() != self.initialPositions[item]:
+ self.itemMoved(item, self.initialPositions[item])
+ self.movingItems = []
+ self.initialPositions = {}
+ return super(CustomScene, self).mouseReleaseEvent(event)"""
+
+ # The above mouse events are for moving items on top of each other.
+
+ """def mousePressEvent(self, event):
# overloaded mouse press event to check if an item was moved
bdsp = event.buttonDownScenePos(Qt.LeftButton) #get click pos
point = QPointF(bdsp.x(), bdsp.y()) #create a Qpoint from click pos
@@ -150,7 +239,9 @@ class CustomScene(QGraphicsScene):
QTransform())
if isinstance(item,shapes.SizeGripItem):
item.parentItem().showLineGripItem()
- super(CustomScene,self).mouseMoveEvent(mouseEvent)
+ super(CustomScene,self).mouseMoveEvent(mouseEvent)"""
+
+ # The above is the original mouse events
def reInsertLines(self):
currentIndex = self.undoStack.index()
diff --git a/src/main/resources/base/config/items.json b/src/main/resources/base/config/items.json
index b1972a1..2815ad0 100644
--- a/src/main/resources/base/config/items.json
+++ b/src/main/resources/base/config/items.json
@@ -78,14 +78,14 @@
"name": "Exchanger",
"icon": "./Heating or Cooling Arrangements/905Exchanger.png",
"class": "Heating or Cooling Arrangements",
- "object": "Exchanger",
+ "object": "Exchanger905",
"args": []
},
"907Kettle Reboiler": {
"name": "Kettle Reboiler",
"icon": "./Heating or Cooling Arrangements/907Kettle Reboiler.png",
"class": "Heating or Cooling Arrangements",
- "object": "KettleReboiler",
+ "object": "KettleReboiler907",
"args": []
},
"Exchanger": {