From 4d1cb634fb37302e96cab95dafbd8f14f2bec852 Mon Sep 17 00:00:00 2001
From: Blaine
Date: Thu, 18 Jun 2020 14:17:51 +0530
Subject: implement header inclusive bottom line
---
src/main/python/utils/streamTable.py | 15 +++++++++++++--
src/main/resources/base/app.qss | 4 ++--
2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/src/main/python/utils/streamTable.py b/src/main/python/utils/streamTable.py
index acccdee..7dfc27f 100644
--- a/src/main/python/utils/streamTable.py
+++ b/src/main/python/utils/streamTable.py
@@ -93,6 +93,7 @@ class streamTable(QTableView):
self.model.updateEvent.connect(self.resizeHandler)
self.setItemDelegateForRow(0, drawBorderDelegate(self))
+ self.borderThickness[0] = True
def mousePressEvent(self, event):
if event.button() == Qt.RightButton:
@@ -109,11 +110,12 @@ class streamTable(QTableView):
def changeRowBorder(self, row):
if self.borderThickness[row]:
- self.borderThickness[row] = False
+ self.borderThickness.pop(row)
self.setItemDelegateForRow(row, QStyledItemDelegate(self))
else:
self.borderThickness[row] = True
self.setItemDelegateForRow(row, drawBorderDelegate(self))
+ self.verticalHeader().repaint()
def labelChange(self, index):
newName, bool = QInputDialog.getText(self, "Change Property Name", "Enter new name",
@@ -180,4 +182,13 @@ class verticalHeader(QHeaderView):
def mouseDoubleClickEvent(self, event):
index = self.logicalIndexAt(event.pos())
self.labelChangeRequested.emit(index)
- return super().mouseDoubleClickEvent(event)
\ No newline at end of file
+ return super().mouseDoubleClickEvent(event)
+
+ def paintSection(self, painter, option, index):
+ painter.save()
+ super(verticalHeader, self).paintSection(painter, option, index)
+ painter.restore()
+ if self.parentWidget().borderThickness[index]:
+ rect = option
+ painter.drawLine(rect.bottomLeft(), rect.bottomRight())
+ painter.setPen(QPen(Qt.black, 1, Qt.SolidLine))
\ No newline at end of file
diff --git a/src/main/resources/base/app.qss b/src/main/resources/base/app.qss
index d7b25b4..1d21ab4 100644
--- a/src/main/resources/base/app.qss
+++ b/src/main/resources/base/app.qss
@@ -275,9 +275,9 @@ QHeaderView::section {
background-color: white;
}
-QHeaderView::section:first{
+/* QHeaderView::section:first{
border-bottom: 1px solid black;
-}
+} */
QTableView {
border: none;
--
cgit
From 384bdf5f033ba1453efdbb8baf43cdaa9049c9df Mon Sep 17 00:00:00 2001
From: Blaine
Date: Thu, 18 Jun 2020 14:27:19 +0530
Subject: fix line updation
---
src/main/python/shapes/line.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/main/python/shapes/line.py b/src/main/python/shapes/line.py
index c893fe6..6883662 100644
--- a/src/main/python/shapes/line.py
+++ b/src/main/python/shapes/line.py
@@ -1008,8 +1008,9 @@ class Line(QGraphicsPathItem):
action = contextMenu.exec_(event.screenPos())
# check for label action and add text label as child
if action == addLableAction:
- print(event.scenePos(), event.pos())
- self.label.append(LineLabel(event.scenePos(), self)) # text label as child
+ label = LineLabel(event.scenePos(), self)
+ self.label.append(label) # text label as child
+ self.scene().labelAdded.emit(label)
def __getstate__(self):
return {
--
cgit
From c0c5fe6186ca5776c9ff8199b88c13c2ad0e72a8 Mon Sep 17 00:00:00 2001
From: Blaine
Date: Thu, 18 Jun 2020 15:43:57 +0530
Subject: save fileupdate
---
src/main/python/shapes/line.py | 11 +++++++++--
src/main/python/utils/app.py | 3 +--
src/main/python/utils/canvas.py | 25 +++++++++++++++----------
src/main/python/utils/streamTable.py | 12 ++++++++++++
4 files changed, 37 insertions(+), 14 deletions(-)
diff --git a/src/main/python/shapes/line.py b/src/main/python/shapes/line.py
index 6883662..57778fa 100644
--- a/src/main/python/shapes/line.py
+++ b/src/main/python/shapes/line.py
@@ -292,13 +292,16 @@ class LineLabel(QGraphicsTextItem):
"text": self.toPlainText(),
"index": self.index,
"gap": self.gap,
- "pos": (self.pos().x(), self.pos().y())
+ "pos": (self.pos().x(), self.pos().y()),
+ "values": self.values
}
def __setstate__(self, dict):
self.setPlainText(dict['text'])
self.index = dict['index']
self.gap = dict['gap']
+ for key, value in dict['values']:
+ self.values[key] = value
def findIndex(line, pos):
@@ -1023,8 +1026,12 @@ class Line(QGraphicsPathItem):
"refLine": hex(id(self.refLine)) if self.refLine else 0,
"refIndex": self.refIndex,
"label": [i for i in self.label],
- "id": hex(id(self))
+ "id": hex(id(self)),
+ "startGap": self.startGap,
+ "endGap": self.endGap
}
def __setstate__(self, dict):
self.points = [QPointF(x, y) for x, y in dict["points"]]
+ self.startGap = dict['startGap']
+ self.endGap = dict['endGap']
diff --git a/src/main/python/utils/app.py b/src/main/python/utils/app.py
index 96a45b0..60ae47f 100644
--- a/src/main/python/utils/app.py
+++ b/src/main/python/utils/app.py
@@ -61,5 +61,4 @@ class JSON_Typer(JSONEncoder):
importer = pyqtProperty(str, fileImporter)
-shapeGrips = {}
-lines = {}
\ No newline at end of file
+memMap = {}
\ No newline at end of file
diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py
index 47e95a9..e492878 100644
--- a/src/main/python/utils/canvas.py
+++ b/src/main/python/utils/canvas.py
@@ -6,7 +6,7 @@ from PyQt5.QtWidgets import (QFileDialog, QApplication, QHBoxLayout, QMenu,
from . import dialogs
from .graphics import customView, customScene
from .data import paperSizes, ppiList, sheetDimensionList
-from .app import shapeGrips, lines
+from .app import memMap
from .streamTable import streamTable, moveRect
import shapes
@@ -142,7 +142,8 @@ class canvas(customView):
"ObjectName": self.objectName(),
"symbols": [i for i in self.painter.items() if isinstance(i, shapes.NodeItem)],
"lines": sorted([i for i in self.painter.items() if isinstance(i, shapes.Line)], key = lambda x: 1 if x.refLine else 0),
- "landscape": self.landscape
+ "landscape": self.landscape,
+ "streamTable": [self.streamTable, (self.streamTableRect.pos().x(), self.streamTable.pos().y())] if self.streamTable else False
}
def __setstate__(self, dict):
@@ -159,7 +160,7 @@ class canvas(customView):
graphic.updateLineGripItem()
graphic.updateSizeGripItem()
for gripitem in item['lineGripItems']:
- shapeGrips[gripitem[0]] = (graphic, gripitem[1])
+ memMap[gripitem[0]] = (graphic, gripitem[1])
if item['label']:
graphicLabel = shapes.ItemLabel(pos = QPointF(*item['label']['pos']), parent = graphic)
graphicLabel.__setstate__(item['label'])
@@ -167,19 +168,19 @@ class canvas(customView):
for item in dict['lines']:
line = shapes.Line(QPointF(*item['startPoint']), QPointF(*item['endPoint']))
- lines[item['id']] = line
+ memMap[item['id']] = line
line.__setstate__(dict = item)
self.painter.addItem(line)
- graphic, index = shapeGrips[item['startGripItem']]
+ graphic, index = memMap[item['startGripItem']]
line.startGripItem = graphic.lineGripItems[index]
graphic.lineGripItems[index].line = line
if item['endGripItem']:
- graphic, index = shapeGrips[item['endGripItem']]
+ graphic, index = memMap[item['endGripItem']]
line.endGripItem = graphic.lineGripItems[index]
graphic.lineGripItems[index].line = line
else:
- line.refLine = lines[item['refLine']]
- lines[item['refLine']].midLines.append(line)
+ line.refLine = memMap[item['refLine']]
+ memMap[item['refLine']].midLines.append(line)
line.refIndex = item['refIndex']
for label in item['label']:
labelItem = shapes.LineLabel(QPointF(*label['pos']), line)
@@ -189,8 +190,12 @@ class canvas(customView):
line.updateLine()
line.addGrabber()
- shapeGrips.clear()
- lines.clear()
+ if dict['streamTable']:
+ table = streamTable(self.labelItems, self)
+ self.addStreamTable(QPointF(*dict['streamTable'][1]), table)
+ table.__setstate__(dict['streamTable'][0])
+
+ memMap.clear()
self.painter.advance()
diff --git a/src/main/python/utils/streamTable.py b/src/main/python/utils/streamTable.py
index 7dfc27f..52b62c1 100644
--- a/src/main/python/utils/streamTable.py
+++ b/src/main/python/utils/streamTable.py
@@ -147,6 +147,18 @@ class streamTable(QTableView):
for i in range(self.model.rowCount()):
h += self.rowHeight(i)
return QRect(0, 0, w, h)
+
+ def __getstate__(self):
+ return {
+ "borderThickness": self.borderThickness,
+ "header": self.model.header
+ }
+
+ def __setstate__(self, dict):
+ for key, value in dict['borderThickness']:
+ self.borderThickness[key] = value
+ self.model.header = dict['header']
+ self.repaint()
class drawBorderDelegate(QStyledItemDelegate):
--
cgit
From 85a2d6f42168a9e693b7649b979b86f7a94d6ca3 Mon Sep 17 00:00:00 2001
From: Blaine
Date: Thu, 18 Jun 2020 15:59:40 +0530
Subject: save update 2
---
src/main/python/shapes/line.py | 4 +++-
src/main/python/shapes/shapes.py | 3 ++-
src/main/python/utils/canvas.py | 4 +++-
src/main/python/utils/streamTable.py | 2 +-
4 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/src/main/python/shapes/line.py b/src/main/python/shapes/line.py
index 57778fa..856869d 100644
--- a/src/main/python/shapes/line.py
+++ b/src/main/python/shapes/line.py
@@ -300,7 +300,7 @@ class LineLabel(QGraphicsTextItem):
self.setPlainText(dict['text'])
self.index = dict['index']
self.gap = dict['gap']
- for key, value in dict['values']:
+ for key, value in dict['values'].items():
self.values[key] = value
@@ -1033,5 +1033,7 @@ class Line(QGraphicsPathItem):
def __setstate__(self, dict):
self.points = [QPointF(x, y) for x, y in dict["points"]]
+ self.startPoint = QPointF(*dict['startPoint'])
+ self.endPoint = QPointF(*dict['endPoint'])
self.startGap = dict['startGap']
self.endGap = dict['endGap']
diff --git a/src/main/python/shapes/shapes.py b/src/main/python/shapes/shapes.py
index 7205ba7..d492568 100644
--- a/src/main/python/shapes/shapes.py
+++ b/src/main/python/shapes/shapes.py
@@ -616,7 +616,8 @@ class NodeItem(QGraphicsSvgItem):
"height": self.height,
"pos": (self.pos().x(), self.pos().y()),
"lineGripItems": [(hex(id(i)), i.m_index) for i in self.lineGripItems],
- "label": self.label
+ "label": self.label,
+ "rotation": self.rotation
}
def __setstate__(self, dict):
diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py
index e492878..ad8981d 100644
--- a/src/main/python/utils/canvas.py
+++ b/src/main/python/utils/canvas.py
@@ -143,7 +143,7 @@ class canvas(customView):
"symbols": [i for i in self.painter.items() if isinstance(i, shapes.NodeItem)],
"lines": sorted([i for i in self.painter.items() if isinstance(i, shapes.Line)], key = lambda x: 1 if x.refLine else 0),
"landscape": self.landscape,
- "streamTable": [self.streamTable, (self.streamTableRect.pos().x(), self.streamTable.pos().y())] if self.streamTable else False
+ "streamTable": [self.streamTable, (self.streamTableRect.pos().x(), self.streamTableRect.pos().y())] if self.streamTable else False
}
def __setstate__(self, dict):
@@ -165,6 +165,7 @@ class canvas(customView):
graphicLabel = shapes.ItemLabel(pos = QPointF(*item['label']['pos']), parent = graphic)
graphicLabel.__setstate__(item['label'])
self.painter.addItem(graphicLabel)
+ graphic.rotation = item['rotation']
for item in dict['lines']:
line = shapes.Line(QPointF(*item['startPoint']), QPointF(*item['endPoint']))
@@ -189,6 +190,7 @@ class canvas(customView):
self.painter.addItem(labelItem)
line.updateLine()
line.addGrabber()
+ print(line.startGripItem)
if dict['streamTable']:
table = streamTable(self.labelItems, self)
diff --git a/src/main/python/utils/streamTable.py b/src/main/python/utils/streamTable.py
index 52b62c1..b397016 100644
--- a/src/main/python/utils/streamTable.py
+++ b/src/main/python/utils/streamTable.py
@@ -155,7 +155,7 @@ class streamTable(QTableView):
}
def __setstate__(self, dict):
- for key, value in dict['borderThickness']:
+ for key, value in dict['borderThickness'].items():
self.borderThickness[key] = value
self.model.header = dict['header']
self.repaint()
--
cgit
From 5d08ffb7b9f28b9bd641c1d5981ea8b52f531c94 Mon Sep 17 00:00:00 2001
From: Blaine
Date: Thu, 18 Jun 2020 16:03:21 +0530
Subject: save update 3
---
src/main/python/utils/canvas.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py
index ad8981d..d5888bf 100644
--- a/src/main/python/utils/canvas.py
+++ b/src/main/python/utils/canvas.py
@@ -174,11 +174,11 @@ class canvas(customView):
self.painter.addItem(line)
graphic, index = memMap[item['startGripItem']]
line.startGripItem = graphic.lineGripItems[index]
- graphic.lineGripItems[index].line = line
+ graphic.lineGripItems[index].lines.append(line)
if item['endGripItem']:
graphic, index = memMap[item['endGripItem']]
line.endGripItem = graphic.lineGripItems[index]
- graphic.lineGripItems[index].line = line
+ graphic.lineGripItems[index].lines.append(line)
else:
line.refLine = memMap[item['refLine']]
memMap[item['refLine']].midLines.append(line)
--
cgit
From 7f0ed11a3763ed1463519905f0b7e522bbbd2ee2 Mon Sep 17 00:00:00 2001
From: Blaine
Date: Thu, 18 Jun 2020 16:04:25 +0530
Subject: logging fix
---
src/main/python/shapes/shapes.py | 2 +-
src/main/python/utils/canvas.py | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/main/python/shapes/shapes.py b/src/main/python/shapes/shapes.py
index d492568..0d28a00 100644
--- a/src/main/python/shapes/shapes.py
+++ b/src/main/python/shapes/shapes.py
@@ -267,7 +267,7 @@ class LineGripItem(QGraphicsPathItem):
if self.size:
painter.save()
pen = self.pen()
- pen.setWidth(-1)
+ pen.setWidth(1)
painter.setPen(pen)
painter.drawPath(self.path())
painter.restore()
diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py
index d5888bf..a75570c 100644
--- a/src/main/python/utils/canvas.py
+++ b/src/main/python/utils/canvas.py
@@ -190,7 +190,6 @@ class canvas(customView):
self.painter.addItem(labelItem)
line.updateLine()
line.addGrabber()
- print(line.startGripItem)
if dict['streamTable']:
table = streamTable(self.labelItems, self)
--
cgit
From 11c4c315e4616259b2c6813df94a3990784df781 Mon Sep 17 00:00:00 2001
From: Blaine
Date: Thu, 18 Jun 2020 16:21:11 +0530
Subject: minor fixes 2
---
src/main/python/utils/streamTable.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/main/python/utils/streamTable.py b/src/main/python/utils/streamTable.py
index b397016..c8e682c 100644
--- a/src/main/python/utils/streamTable.py
+++ b/src/main/python/utils/streamTable.py
@@ -47,6 +47,7 @@ class streamTableModel(QAbstractTableModel):
int = int if int else self.rowCount()+1
self.beginInsertColumns(QModelIndex(), int, int)
self.list.insert(int, item)
+ item.nameChanged.connect(self.parent().repaint)
self.endInsertColumns()
self.updateEvent.emit()
--
cgit
From 420d0c3a68aa4a649991d36f0f72772fab0dd2d4 Mon Sep 17 00:00:00 2001
From: Blaine
Date: Thu, 18 Jun 2020 16:55:12 +0530
Subject: flipping feature
---
src/main/python/shapes/shapes.py | 59 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 58 insertions(+), 1 deletion(-)
diff --git a/src/main/python/shapes/shapes.py b/src/main/python/shapes/shapes.py
index 0d28a00..f47ea28 100644
--- a/src/main/python/shapes/shapes.py
+++ b/src/main/python/shapes/shapes.py
@@ -244,7 +244,12 @@ class LineGripItem(QGraphicsPathItem):
@property
def m_location(self):
- return directionsEnum[(self._m_location + self.parentItem().rotation)%4]
+ index = (self._m_location + self.parentItem().rotation)
+ if index%2:
+ index = (index + 2*self.parentItem().flipH)%4
+ else:
+ index = (index + 2*self.parentItem().flipV)%4
+ return directionsEnum[index]
@m_location.setter
def m_location(self, location):
@@ -451,7 +456,55 @@ class NodeItem(QGraphicsSvgItem):
self.sizeGripItems = []
self.label = None
self._rotation = 0
+ self.flipState = [False, False]
+
+ @property
+ def flipH(self):
+ return self.flipState[0]
+
+ @property
+ def flipV(self):
+ return self.flipState[1]
+
+ @flipH.setter
+ def flipH(self, state):
+ transform = QTransform()
+ if self.flipV and state:
+ self.flipState = [False, False]
+ self.rotation = self.rotation % 4
+ transform.scale(1, 1)
+ else:
+ self.flipState[0] = state
+ if state:
+ transform.scale(-1, 1)
+ else:
+ transform.scale(1, 1)
+ self.setTransform(transform)
+ for i in self.lineGripItems:
+ i.updatePosition()
+ for j in i.lines:
+ j.createPath()
+ @flipV.setter
+ def flipV(self, state):
+ transform = QTransform()
+ if self.flipH and state:
+ self.flipState = [False, False]
+ self.rotation = self.rotation % 4
+ transform.scale(1, 1)
+ else:
+ self.flipState[1] = state
+ transform = QTransform()
+ if state:
+ transform.scale(1, -1)
+ else:
+ transform.scale(1, 1)
+ self.setTransform(transform)
+ for i in self.lineGripItems:
+ i.updatePosition()
+ for j in i.lines:
+ j.createPath()
+
@property
def rotation(self):
return self._rotation
@@ -604,6 +657,10 @@ class NodeItem(QGraphicsSvgItem):
# create a menu and add action
contextMenu = QMenu()
addLableAction = contextMenu.addAction("add Label") # add action for text label
+ contextMenu.addAction("Rotate right", lambda : setattr(self, "rotation", self.rotation + 1))
+ contextMenu.addAction("Rotate left", lambda : setattr(self, "rotation", self.rotation - 1))
+ contextMenu.addAction("Flip Horizontally", lambda: setattr(self, "flipH", not self.flipH))
+ contextMenu.addAction("Flip Vertically", lambda: setattr(self, "flipV", not self.flipV))
action = contextMenu.exec_(event.screenPos())
# check for label action and add text label as child
if action == addLableAction:
--
cgit
From 70e9fc3756d8e94c374f498a63105f7345d7e7e2 Mon Sep 17 00:00:00 2001
From: Blaine
Date: Thu, 18 Jun 2020 16:57:38 +0530
Subject: flipstate
---
src/main/python/shapes/shapes.py | 3 ++-
src/main/python/utils/canvas.py | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/main/python/shapes/shapes.py b/src/main/python/shapes/shapes.py
index f47ea28..01ec196 100644
--- a/src/main/python/shapes/shapes.py
+++ b/src/main/python/shapes/shapes.py
@@ -674,7 +674,8 @@ class NodeItem(QGraphicsSvgItem):
"pos": (self.pos().x(), self.pos().y()),
"lineGripItems": [(hex(id(i)), i.m_index) for i in self.lineGripItems],
"label": self.label,
- "rotation": self.rotation
+ "rotation": self.rotation,
+ "flipstate": self.flipState
}
def __setstate__(self, dict):
diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py
index a75570c..b60f11c 100644
--- a/src/main/python/utils/canvas.py
+++ b/src/main/python/utils/canvas.py
@@ -166,6 +166,7 @@ class canvas(customView):
graphicLabel.__setstate__(item['label'])
self.painter.addItem(graphicLabel)
graphic.rotation = item['rotation']
+ graphic.flipH, graphic.flipV = item['flipstate']
for item in dict['lines']:
line = shapes.Line(QPointF(*item['startPoint']), QPointF(*item['endPoint']))
--
cgit
From c7f8e571cb9d7be21eb5b2a7c3c0e4704ffdce9c Mon Sep 17 00:00:00 2001
From: Blaine
Date: Thu, 18 Jun 2020 20:28:29 +0530
Subject: ignore build
---
.gitignore | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index 9aeb547..0e61b94 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,5 @@ src/main/python/experimental/*
*.pfd
.vscode
.vscode/*.jsons
-.idea/*
\ No newline at end of file
+.idea/*
+target/*
--
cgit
From 025cd829d956f5081e034f60b69413ec4432e0e8 Mon Sep 17 00:00:00 2001
From: Blaine
Date: Fri, 19 Jun 2020 03:03:41 +0530
Subject: rework flip feature
---
src/main/python/shapes/shapes.py | 40 +++++++++++-----------------------------
1 file changed, 11 insertions(+), 29 deletions(-)
diff --git a/src/main/python/shapes/shapes.py b/src/main/python/shapes/shapes.py
index 01ec196..aae8f47 100644
--- a/src/main/python/shapes/shapes.py
+++ b/src/main/python/shapes/shapes.py
@@ -466,44 +466,26 @@ class NodeItem(QGraphicsSvgItem):
def flipV(self):
return self.flipState[1]
- @flipH.setter
- def flipH(self, state):
+ def flip(self):
transform = QTransform()
- if self.flipV and state:
- self.flipState = [False, False]
- self.rotation = self.rotation % 4
- transform.scale(1, 1)
- else:
- self.flipState[0] = state
- if state:
- transform.scale(-1, 1)
- else:
- transform.scale(1, 1)
+ h = -1 if self.flipH else 1
+ w = -1 if self.flipV else 1
+ transform.scale(h, w)
self.setTransform(transform)
for i in self.lineGripItems:
i.updatePosition()
for j in i.lines:
j.createPath()
+
+ @flipH.setter
+ def flipH(self, state):
+ self.flipState[0] = state
+ self.flip()
@flipV.setter
def flipV(self, state):
- transform = QTransform()
- if self.flipH and state:
- self.flipState = [False, False]
- self.rotation = self.rotation % 4
- transform.scale(1, 1)
- else:
- self.flipState[1] = state
- transform = QTransform()
- if state:
- transform.scale(1, -1)
- else:
- transform.scale(1, 1)
- self.setTransform(transform)
- for i in self.lineGripItems:
- i.updatePosition()
- for j in i.lines:
- j.createPath()
+ self.flipState[1] = state
+ self.flip()
@property
def rotation(self):
--
cgit
From 6a306ce01a9501f5580e81e9263cd34987ba7bc4 Mon Sep 17 00:00:00 2001
From: Blaine
Date: Fri, 19 Jun 2020 11:40:28 +0530
Subject: unified transform
---
src/main/python/shapes/shapes.py | 22 +++++++++-------------
1 file changed, 9 insertions(+), 13 deletions(-)
diff --git a/src/main/python/shapes/shapes.py b/src/main/python/shapes/shapes.py
index aae8f47..3efabbc 100644
--- a/src/main/python/shapes/shapes.py
+++ b/src/main/python/shapes/shapes.py
@@ -244,6 +244,8 @@ class LineGripItem(QGraphicsPathItem):
@property
def m_location(self):
+ if self.parentItem().__class__ == Line:
+ return directionsEnum[self._m_location]
index = (self._m_location + self.parentItem().rotation)
if index%2:
index = (index + 2*self.parentItem().flipH)%4
@@ -466,26 +468,27 @@ class NodeItem(QGraphicsSvgItem):
def flipV(self):
return self.flipState[1]
- def flip(self):
+ def updateTransformation(self):
transform = QTransform()
h = -1 if self.flipH else 1
w = -1 if self.flipV else 1
+ transform.rotate(90*self.rotation)
transform.scale(h, w)
self.setTransform(transform)
+ self.setTransform(transform)
for i in self.lineGripItems:
+ i.setTransform(transform)
i.updatePosition()
- for j in i.lines:
- j.createPath()
@flipH.setter
def flipH(self, state):
self.flipState[0] = state
- self.flip()
+ self.updateTransformation()
@flipV.setter
def flipV(self, state):
self.flipState[1] = state
- self.flip()
+ self.updateTransformation()
@property
def rotation(self):
@@ -494,14 +497,7 @@ class NodeItem(QGraphicsSvgItem):
@rotation.setter
def rotation(self, rotation):
self._rotation = rotation % 4
- transform = QTransform()
- transform.rotate(90*rotation)
- self.setTransform(transform)
- for i in self.lineGripItems:
- i.setTransform(transform)
- i.updatePosition()
- for j in i.lines:
- j.createPath()
+ self.updateTransformation()
def boundingRect(self):
"""Overrides QGraphicsSvgItem's boundingRect() virtual public function and
--
cgit
From adbe155abe6604b07c8ef076311f3e9e7a8268b0 Mon Sep 17 00:00:00 2001
From: Blaine
Date: Fri, 19 Jun 2020 11:42:46 +0530
Subject: undo add
---
src/main/python/main.py | 2 +-
src/main/python/utils/graphics.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/python/main.py b/src/main/python/main.py
index 4cf1791..43dcbf3 100644
--- a/src/main/python/main.py
+++ b/src/main/python/main.py
@@ -77,8 +77,8 @@ class appWindow(QMainWindow):
graphic = getattr(shapes, object['object'])(*map(lambda x: int(x) if x.isdigit() else x, object['args']))
# graphic.setPen(QPen(Qt.black, 2))
# graphic.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable)
- currentDiagram.addItemPlus(graphic)
graphic.setPos(20, 20)
+ currentDiagram.addItemPlus(graphic)
def newProject(self):
#call to create a new file inside mdi area
diff --git a/src/main/python/utils/graphics.py b/src/main/python/utils/graphics.py
index 3e1d193..0dca012 100644
--- a/src/main/python/utils/graphics.py
+++ b/src/main/python/utils/graphics.py
@@ -49,8 +49,8 @@ class customView(QGraphicsView):
graphic = getattr(shapes, obj[0])(*map(lambda x: int(x) if x.isdigit() else x, obj[1:]))
# graphic.setPen(QPen(Qt.black, 2))
# graphic.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable)
- self.scene().addItemPlus(graphic)
graphic.setPos(QDropEvent.pos().x(), QDropEvent.pos().y())
+ self.scene().addItemPlus(graphic)
QDropEvent.acceptProposedAction()
def wheelEvent(self, QWheelEvent):
--
cgit
From cadf8eade6e9d1f5f1a1fe3205bccef41ca5e3e8 Mon Sep 17 00:00:00 2001
From: Blaine
Date: Fri, 19 Jun 2020 11:43:58 +0530
Subject: undo add 2
---
src/main/python/utils/undo.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/python/utils/undo.py b/src/main/python/utils/undo.py
index 8426494..92a8de8 100644
--- a/src/main/python/utils/undo.py
+++ b/src/main/python/utils/undo.py
@@ -26,7 +26,7 @@ class addCommand(QUndoCommand):
self.scene = scene
self.diagramItem = addItem
self.itemPos = addItem.pos()
- self.setText(f"Add {objectName(self.diagramItem)}")
+ self.setText(f"Add {objectName(self.diagramItem)} at {self.itemPos.x()}, {self.itemPos.y()}")
def undo(self):
self.scene.removeItem(self.diagramItem)
--
cgit
From ddcfa2fd395be6d0ac261851ff6eb31be2164728 Mon Sep 17 00:00:00 2001
From: Blaine
Date: Fri, 19 Jun 2020 12:17:59 +0530
Subject: update shortcuts
---
src/main/python/main.py | 46 ++++++++++++++++-----------------------
src/main/python/utils/graphics.py | 7 +++---
2 files changed, 23 insertions(+), 30 deletions(-)
diff --git a/src/main/python/main.py b/src/main/python/main.py
index 43dcbf3..7a73c7a 100644
--- a/src/main/python/main.py
+++ b/src/main/python/main.py
@@ -2,7 +2,7 @@ import sys
from fbs_runtime.application_context.PyQt5 import ApplicationContext
from PyQt5.QtCore import QObject, Qt, pyqtSignal, QSize, QPoint
-from PyQt5.QtGui import QBrush, QColor, QImage, QPainter, QPalette, QPen
+from PyQt5.QtGui import QBrush, QColor, QImage, QPainter, QPalette, QPen, QKeySequence
from PyQt5.QtWidgets import (QComboBox, QFileDialog, QFormLayout, QVBoxLayout,
QHBoxLayout, QLabel, QMainWindow, QMenu,
QPushButton, QWidget, QMdiArea, QSplitter, QGraphicsItem)
@@ -29,19 +29,29 @@ class appWindow(QMainWindow):
# self.mainWidget.setObjectName("Main Widget")
self.menuFile = titleMenu.addMenu('File') #File Menu
- self.menuFile.addAction("New", self.newProject)
- self.menuFile.addAction("Open", self.openProject)
- self.menuFile.addAction("Save", self.saveProject)
+ newAction = self.menuFile.addAction("New", self.newProject)
+ openAction = self.menuFile.addAction("Open", self.openProject)
+ saveAction = self.menuFile.addAction("Save", self.saveProject)
+
+ newAction.setShortcut(QKeySequence.New)
+ openAction.setShortcut(QKeySequence.Open)
+ saveAction.setShortcut(QKeySequence.Save)
self.menuEdit = titleMenu.addMenu('Edit')
- self.undo = self.menuEdit.addAction("Undo", lambda x=self: x.activeScene.painter.undoAction.trigger())
- self.redo = self.menuEdit.addAction("Redo", lambda x=self: x.activeScene.painter.redoAction.trigger())
+ undoAction = self.undo = self.menuEdit.addAction("Undo", lambda x=self: x.activeScene.painter.undoAction.trigger())
+ redoAction = self.redo = self.menuEdit.addAction("Redo", lambda x=self: x.activeScene.painter.redoAction.trigger())
+
+ undoAction.setShortcut(QKeySequence.Undo)
+ redoAction.setShortcut(QKeySequence.Redo)
self.menuEdit.addAction("Show Undo Stack", lambda x=self: x.activeScene.painter.createUndoView(self) )
self.menuGenerate = titleMenu.addMenu('Generate') #Generate menu
- self.menuGenerate.addAction("Image", self.saveImage)
- self.menuGenerate.addAction("Report", self.generateReport)
+ imageAction = self.menuGenerate.addAction("Image", self.saveImage)
+ reportAction = self.menuGenerate.addAction("Report", self.generateReport)
+
+ imageAction.setShortcut(QKeySequence("Ctrl+P"))
+ reportAction.setShortcut(QKeySequence("Ctrl+R"))
self.mdi = QMdiArea(self) #create area for files to be displayed
self.mdi.setObjectName('mdi area')
@@ -185,25 +195,7 @@ class appWindow(QMainWindow):
def keyPressEvent(self, event):
#overload key press event for custom keyboard shortcuts
if event.modifiers() & Qt.ControlModifier:
- if event.key() == Qt.Key_N:
- self.newProject()
-
- elif event.key() == Qt.Key_S:
- self.saveProject()
-
- elif event.key() == Qt.Key_O:
- self.openProject()
-
- elif event.key() == Qt.Key_W:
- self.close()
-
- elif event.key() == Qt.Key_P:
- if Qt.AltModifier:
- self.saveImage()
- else:
- self.generateReport()
-
- elif event.key() == Qt.Key_A:
+ if event.key() == Qt.Key_A:
#todo implement selectAll
for item in self.mdi.activeSubWindow().tabber.currentWidget().items:
item.setSelected(True)
diff --git a/src/main/python/utils/graphics.py b/src/main/python/utils/graphics.py
index 0dca012..a9820a2 100644
--- a/src/main/python/utils/graphics.py
+++ b/src/main/python/utils/graphics.py
@@ -22,9 +22,10 @@ class customView(QGraphicsView):
self.setAcceptDrops(True) #sets ability to accept drops
if scene:
#create necessary undo redo actions to accept keyboard shortcuts
- self.addAction(scene.undoAction)
- self.addAction(scene.redoAction)
- self.addAction(scene.deleteAction)
+ # self.addAction(scene.undoAction)
+ # self.addAction(scene.redoAction)
+ # self.addAction(scene.deleteAction)
+ pass
#following four functions are required to be overridden for drag-drop functionality
def dragEnterEvent(self, QDragEnterEvent):
--
cgit
From 7e779cddeb822b727e944e1d54237bed4b5692a9 Mon Sep 17 00:00:00 2001
From: Blaine
Date: Fri, 19 Jun 2020 13:44:01 +0530
Subject: camelCase to PascalCase for class names
---
src/main/python/main.py | 6 +++---
src/main/python/utils/canvas.py | 6 +++---
src/main/python/utils/fileWindow.py | 12 ++++++------
src/main/python/utils/graphics.py | 16 ++++++++--------
src/main/python/utils/tabs.py | 12 ++++++------
src/main/python/utils/toolbar.py | 6 +++---
6 files changed, 29 insertions(+), 29 deletions(-)
diff --git a/src/main/python/main.py b/src/main/python/main.py
index 7a73c7a..9683f00 100644
--- a/src/main/python/main.py
+++ b/src/main/python/main.py
@@ -8,7 +8,7 @@ from PyQt5.QtWidgets import (QComboBox, QFileDialog, QFormLayout, QVBoxLayout,
QPushButton, QWidget, QMdiArea, QSplitter, QGraphicsItem)
from utils.canvas import canvas
-from utils.fileWindow import fileWindow
+from utils.fileWindow import FileWindow
from utils.data import ppiList, sheetDimensionList
from utils import dialogs
from utils.toolbar import toolbar
@@ -92,7 +92,7 @@ class appWindow(QMainWindow):
def newProject(self):
#call to create a new file inside mdi area
- project = fileWindow(self.mdi)
+ project = FileWindow(self.mdi)
project.setObjectName("New Project")
self.mdi.addSubWindow(project)
if not project.tabList: # important when unpickling a file instead
@@ -110,7 +110,7 @@ class appWindow(QMainWindow):
for files in name[0]:
with open(files,'r') as file:
projectData = load(file)
- project = fileWindow(self.mdi)
+ project = FileWindow(self.mdi)
self.mdi.addSubWindow(project)
project.__setstate__(projectData)
project.resizeHandler()
diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py
index b60f11c..8608f7b 100644
--- a/src/main/python/utils/canvas.py
+++ b/src/main/python/utils/canvas.py
@@ -4,14 +4,14 @@ from PyQt5.QtWidgets import (QFileDialog, QApplication, QHBoxLayout, QMenu,
QTabWidget, QWidget, QSpacerItem, QStyle, QGraphicsProxyWidget)
from . import dialogs
-from .graphics import customView, customScene
+from .graphics import CustomView, CustomScene
from .data import paperSizes, ppiList, sheetDimensionList
from .app import memMap
from .streamTable import streamTable, moveRect
import shapes
-class canvas(customView):
+class canvas(CustomView):
"""
Defines the work area for a single sheet. Contains a QGraphicScene along with necessary properties
for context menu and dialogs.
@@ -30,7 +30,7 @@ class canvas(customView):
# when we will draw items on this, this might be changed if QGraphicScene is subclassed.
#set layout and background color
- self.painter = customScene()
+ self.painter = CustomScene()
self.painter.labelAdded.connect(self.updateStreamTable)
self.painter.setBackgroundBrush(QBrush(Qt.white)) #set white background
self.setScene(self.painter)
diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py
index e85d513..b2f5304 100644
--- a/src/main/python/utils/fileWindow.py
+++ b/src/main/python/utils/fileWindow.py
@@ -5,14 +5,14 @@ from PyQt5.QtWidgets import (QFileDialog, QHBoxLayout,
QSplitter, QWidget, QStyle, QSizePolicy)
from os import path
from . import dialogs
-from .graphics import customView
+from .graphics import CustomView
from .canvas import canvas
-from .tabs import customTabWidget
+from .tabs import CustomTabWidget
from .undo import resizeCommand
from .app import dump, loads, JSON_Typer, version
-class fileWindow(QMdiSubWindow):
+class FileWindow(QMdiSubWindow):
"""
This defines a single file, inside the application, consisting of multiple tabs that contain
canvases. Pre-Defined so that a file can be instantly created without defining the structure again.
@@ -21,14 +21,14 @@ class fileWindow(QMdiSubWindow):
tabChangeEvent = pyqtSignal()
def __init__(self, parent = None, title = 'New Project', size = 'A0', ppi = '72'):
- super(fileWindow, self).__init__(parent)
+ super(FileWindow, self).__init__(parent)
self._sideViewTab = None
self.index = None
self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
#Uses a custom QTabWidget that houses a custom new Tab Button, used to house the seperate
# diagrams inside a file
- self.tabber = customTabWidget(self)
+ self.tabber = CustomTabWidget(self)
self.tabber.setObjectName(title) #store title as object name for pickling
self.tabber.tabCloseRequested.connect(self.closeTab) # Show save alert on tab close
self.tabber.currentChanged.connect(self.changeTab) # placeholder just to detect tab change
@@ -67,7 +67,7 @@ class fileWindow(QMdiSubWindow):
def createSideViewArea(self):
#creates the side view widgets and sets them to invisible
# self.splitter = QSplitter(Qt.Vertical ,self)
- self.sideView = customView(parent = self)
+ self.sideView = CustomView(parent = self)
self.sideView.setInteractive(False)
self.sideViewCloseButton = QPushButton('×', self.sideView)
self.sideViewCloseButton.setObjectName("sideViewCloseButton")
diff --git a/src/main/python/utils/graphics.py b/src/main/python/utils/graphics.py
index a9820a2..05ffc46 100644
--- a/src/main/python/utils/graphics.py
+++ b/src/main/python/utils/graphics.py
@@ -7,16 +7,16 @@ from .dialogs import showUndoDialog
import shapes
-class customView(QGraphicsView):
+class CustomView(QGraphicsView):
"""
Defines custom QGraphicsView with zoom features and drag-drop accept event, overriding wheel event
"""
def __init__(self, scene = None, parent=None):
if scene is not None: #overloaded constructor
- super(customView, self).__init__(scene, parent)
+ super(CustomView, self).__init__(scene, parent)
else:
- super(customView, self).__init__(parent)
+ super(CustomView, self).__init__(parent)
self._zoom = 1
self.setDragMode(True) #sets pannable using mouse
self.setAcceptDrops(True) #sets ability to accept drops
@@ -67,7 +67,7 @@ class customView(QGraphicsView):
self.zoom += QWheelEvent.angleDelta().y()
QWheelEvent.accept() # accept event so that scrolling doesnt happen simultaneously
else:
- return super(customView, self).wheelEvent(QWheelEvent) # scroll if ctrl not pressed
+ return super(CustomView, self).wheelEvent(QWheelEvent) # scroll if ctrl not pressed
@property
def zoom(self):
@@ -81,14 +81,14 @@ class customView(QGraphicsView):
self._zoom = value
self.scale(self.zoom / temp, self.zoom / temp)
-class customScene(QGraphicsScene):
+class CustomScene(QGraphicsScene):
"""
Extends QGraphicsScene with undo-redo functionality
"""
labelAdded = pyqtSignal(shapes.QGraphicsItem)
def __init__(self, *args, parent=None):
- super(customScene, self).__init__(*args, parent=parent)
+ super(CustomScene, self).__init__(*args, parent=parent)
self.undoStack = QUndoStack(self) #Used to store undo-redo moves
self.createActions() #creates necessary actions that need to be called for undo-redo
@@ -133,7 +133,7 @@ class customScene(QGraphicsScene):
if self.movingItem and event.button() == Qt.LeftButton:
self.oldPos = self.movingItem.pos() #if left click is held, then store old pos
self.clearSelection() #clears selected items
- return super(customScene, self).mousePressEvent(event)
+ return super(CustomScene, self).mousePressEvent(event)
def mouseReleaseEvent(self, event):
# overloaded mouse release event to check if an item was moved
@@ -142,4 +142,4 @@ class customScene(QGraphicsScene):
#if item pos had changed, when mouse was realeased, emit itemMoved signal
self.itemMoved(self.movingItem, self.oldPos)
self.movingItem = None #clear movingitem reference
- return super(customScene, self).mouseReleaseEvent(event)
+ return super(CustomScene, self).mouseReleaseEvent(event)
diff --git a/src/main/python/utils/tabs.py b/src/main/python/utils/tabs.py
index 1186191..cedb298 100644
--- a/src/main/python/utils/tabs.py
+++ b/src/main/python/utils/tabs.py
@@ -1,7 +1,7 @@
from PyQt5.QtWidgets import QTabBar, QPushButton, QTabWidget, QInputDialog
from PyQt5.QtCore import pyqtSignal, QSize, Qt
-class tabBarPlus(QTabBar):
+class TabBarPlus(QTabBar):
"""
Just implemented to overload resize and layout change to emit a signal
"""
@@ -26,17 +26,17 @@ class tabBarPlus(QTabBar):
self.nameChanged.emit(index, newName)
-class customTabWidget(QTabWidget):
+class CustomTabWidget(QTabWidget):
"""
QTabWidget with a new tab button, also catches layoutChange signal by
- the tabBarPlus to dynamically move the button to the correct location
+ the TabBarPlus to dynamically move the button to the correct location
"""
plusClicked = pyqtSignal()
def __init__(self, parent=None):
- super(customTabWidget, self).__init__(parent)
+ super(CustomTabWidget, self).__init__(parent)
- self.tab = tabBarPlus()
- self.setTabBar(self.tab) #set tabBar to our custom tabBarPlus
+ self.tab = TabBarPlus()
+ self.setTabBar(self.tab) #set tabBar to our custom TabBarPlus
self.plusButton = QPushButton('+', self) #create the new tab button
#style the new tab button
diff --git a/src/main/python/utils/toolbar.py b/src/main/python/utils/toolbar.py
index a175aff..3f6338b 100644
--- a/src/main/python/utils/toolbar.py
+++ b/src/main/python/utils/toolbar.py
@@ -107,7 +107,7 @@ class toolbar(QDockWidget):
#helper functions to create required buttons
for itemClass in itemClasses:
self.toolbarButtonDict[itemClass] = {}
- label = sectionLabel(itemClass)
+ label = SectionLabel(itemClass)
self.toolbarLabelDict[itemClass] = label
for item in toolbarItems[itemClass].keys():
obj = toolbarItems[itemClass][item]
@@ -165,7 +165,7 @@ class toolbarButton(QToolButton):
#defines button size
return QSize(55, 55)
-class sectionLabel(QLabel):
+class SectionLabel(QLabel):
def __init__(self, *args):
- super(sectionLabel, self).__init__(*args)
\ No newline at end of file
+ super(SectionLabel, self).__init__(*args)
\ No newline at end of file
--
cgit
From 56471d91921916feb033fba55c6902800ac52b65 Mon Sep 17 00:00:00 2001
From: Blaine
Date: Fri, 19 Jun 2020 15:39:45 +0530
Subject: refined stylesheet
---
src/main/resources/base/app.qss | 77 ++++++++++++++++++-----------------------
1 file changed, 34 insertions(+), 43 deletions(-)
diff --git a/src/main/resources/base/app.qss b/src/main/resources/base/app.qss
index 1d21ab4..866d977 100644
--- a/src/main/resources/base/app.qss
+++ b/src/main/resources/base/app.qss
@@ -37,40 +37,39 @@ QLineEdit {
QLineEdit:focus{
border-color: #7cabf9;
}
-tabBarPlus {
- qproperty-drawBase: 0;
+TabBarPlus {
+ /* qpropery-drawBase: 0; */
left: 5px;
background-color: transparent;
font-size: 15px;
}
-tabBarPlus:focus {
+TabBarPlus:focus {
border: 0px transparent black;
}
-tabBarPlus::close-button {
+TabBarPlus::close-button {
padding: 0px;
margin: 0px;
border-radius: 2px;
- background-image: url("src/main/resources/base/ui/close.png");
background-position: center center;
background-repeat: none;
}
-tabBarPlus::close-button:hover {
+TabBarPlus::close-button:hover {
background-color: #006666;
}
-tabBarPlus::close-button:pressed {
+TabBarPlus::close-button:pressed {
background-color: #adc5ed;
}
-tabBarPlus::scroller { /* the width of the scroll buttons */
+TabBarPlus::scroller { /* the width of the scroll buttons */
width: 20px;
}
-tabBarPlus::tab:top,
-tabBarPlus::tab:bottom {
+TabBarPlus::tab:top,
+TabBarPlus::tab:bottom {
color: black;
border: 1px solid #b6b6b6;
border-left-color: #e6e6e6;
@@ -80,61 +79,60 @@ tabBarPlus::tab:bottom {
width: 100px;
}
-tabBarPlus::tab:top:first,
-tabBarPlus::tab:bottom:first {
+TabBarPlus::tab:top:first,
+TabBarPlus::tab:bottom:first {
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
}
-tabBarPlus::tab:top:last,
-tabBarPlus::tab:bottom:last {
+TabBarPlus::tab:top:last,
+TabBarPlus::tab:bottom:last {
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
border-right-width: 1px;
}
-tabBarPlus::tab:top:selected,
-tabBarPlus::tab:bottom:selected {
+TabBarPlus::tab:top:selected,
+TabBarPlus::tab:bottom:selected {
color: white;
background-color: qlineargradient(spread:pad, x1:1, y1:0.545, x2:1, y2:0, stop:0 #00b0b0, stop:1 #00BaBa);
border-color: #006666;
}
-tabBarPlus::tab:top:!selected:hover,
-tabBarPlus::tab:bottom:!selected:hover {
+TabBarPlus::tab:top:!selected:hover,
+TabBarPlus::tab:bottom:!selected:hover {
color: black;
}
-tabBarPlus::tab:top:only-one ,
-tabBarPlus::tab:bottom:only-one {
+TabBarPlus::tab:top:only-one ,
+TabBarPlus::tab:bottom:only-one {
border: 1px solid #1b3774;
border-radius: 6px;
}
-fileWindow {
+FileWindow {
border-width: 2px;
outline: 0;
color: white;
background-color: white;
}
-fileWindow::title{
+FileWindow::title{
color: black;
border-width: 0px;
text-align: center;
background-color: white;
}
-fileWindow::close-button {
+FileWindow::close-button {
padding: 0px;
margin: 0px;
border-radius: 2px;
- background-image: url("src/main/resources/base/ui/close.png");
background-position: center center;
background-repeat: none;
}
-fileWindow::close-button:hover {
+FileWindow::close-button:hover {
background-color: #004646;
}
-fileWindow::close-button:pressed {
+FileWindow::close-button:pressed {
background-color: #adc5ed;
}
@@ -156,8 +154,6 @@ QDockWidget::float-button {
background: transparent;
subcontrol-origin: padding;
subcontrol-position: right center;
-}
-QDockWidget::float-button {
right: 4px;
}
@@ -166,7 +162,6 @@ QDockWidget::float-button:hover {
}
QDockWidget::float-button:pressed {
- /*padding: 1px -1px -1px 1px;*/
background-color: #e0e0e0;
}
@@ -210,7 +205,7 @@ QToolButton:checked {
border-color: #004646;
}
-sectionLabel{
+SectionLabel{
border-color: #00B8B8;
border-style: solid;
border-width: 0px 0px 2px 0px;
@@ -222,11 +217,11 @@ sectionLabel{
color: gray;
}
-sectionLabel:first{
+SectionLabel:first{
margin-top: 0px;
}
-customView QPushButton{
+CustomView QPushButton{
background-color: rgba(214, 54, 40, 50%);
border: 1px dashed white;
border-radius: 2px;
@@ -235,21 +230,21 @@ customView QPushButton{
padding: 1px 2px 3px 3px;
color: rgba(255, 255, 255, 50%);
}
-customView QPushButton:Hover{
+CustomView QPushButton:Hover{
background-color: rgba(214, 54, 40, 90%);
}
-customTabWidget QPushButton{
+CustomTabWidget QPushButton{
background: rgba(230, 230, 227, 0%);
padding: 1px;
border: 0px solid #E6E6E3;
border-radius: 10px;
}
-customTabWidget QPushButton:hover{
+CustomTabWidget QPushButton:hover{
background: rgba(230, 230, 227, 60%);
}
-customTabWidget::pane {
+CustomTabWidget::pane {
margin: 0px,1px,1px,1px;
border: 2px solid #E6E6E3;
border-radius: 7px;
@@ -260,14 +255,14 @@ canvas{
bottom: -20px;
}
-customTabWidget customView {
+CustomTabWidget CustomView {
border-width: 0px;
padding: 5px;
border-radius: 2px;
}
-QHeaderView {
+/* QHeaderView {
qproperty-defaultAlignment: AlignHCenter;
-}
+} */
QHeaderView::section {
padding: 4px;
@@ -275,10 +270,6 @@ QHeaderView::section {
background-color: white;
}
-/* QHeaderView::section:first{
- border-bottom: 1px solid black;
-} */
-
QTableView {
border: none;
}
--
cgit
From 26dbadc8840cbc5130411ac43f781f82e276bf7e Mon Sep 17 00:00:00 2001
From: Blaine
Date: Fri, 19 Jun 2020 17:29:20 +0530
Subject: cleanup shapes context menu
---
src/main/python/shapes/shapes.py | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/src/main/python/shapes/shapes.py b/src/main/python/shapes/shapes.py
index 3efabbc..ca6490c 100644
--- a/src/main/python/shapes/shapes.py
+++ b/src/main/python/shapes/shapes.py
@@ -634,15 +634,12 @@ class NodeItem(QGraphicsSvgItem):
"""
# create a menu and add action
contextMenu = QMenu()
- addLableAction = contextMenu.addAction("add Label") # add action for text label
- contextMenu.addAction("Rotate right", lambda : setattr(self, "rotation", self.rotation + 1))
- contextMenu.addAction("Rotate left", lambda : setattr(self, "rotation", self.rotation - 1))
+ contextMenu.addAction("Add Label", lambda : setattr(self, "label", ItemLabel(self)))
+ contextMenu.addAction("Rotate right(E)", lambda : setattr(self, "rotation", self.rotation + 1))
+ contextMenu.addAction("Rotate left(Q)", lambda : setattr(self, "rotation", self.rotation - 1))
contextMenu.addAction("Flip Horizontally", lambda: setattr(self, "flipH", not self.flipH))
contextMenu.addAction("Flip Vertically", lambda: setattr(self, "flipV", not self.flipV))
action = contextMenu.exec_(event.screenPos())
- # check for label action and add text label as child
- if action == addLableAction:
- self.label = ItemLabel(self) # text label as child
def __getstate__(self):
return {
--
cgit
From ea0deb05ec943e78652c7c637cbf171e1a697b63 Mon Sep 17 00:00:00 2001
From: Blaine
Date: Sat, 20 Jun 2020 02:33:58 +0530
Subject: new symbol dialog
---
src/main/python/main.py | 8 +-
src/main/python/utils/custom.py | 236 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 243 insertions(+), 1 deletion(-)
create mode 100644 src/main/python/utils/custom.py
diff --git a/src/main/python/main.py b/src/main/python/main.py
index 9683f00..db938b5 100644
--- a/src/main/python/main.py
+++ b/src/main/python/main.py
@@ -45,6 +45,8 @@ class appWindow(QMainWindow):
redoAction.setShortcut(QKeySequence.Redo)
self.menuEdit.addAction("Show Undo Stack", lambda x=self: x.activeScene.painter.createUndoView(self) )
+ self.menuEdit.addSeparator()
+ self.menuEdit.addAction("Add new symbols", self.addSymbolWindow)
self.menuGenerate = titleMenu.addMenu('Generate') #Generate menu
imageAction = self.menuGenerate.addAction("Image", self.saveImage)
@@ -89,7 +91,11 @@ class appWindow(QMainWindow):
# graphic.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable)
graphic.setPos(20, 20)
currentDiagram.addItemPlus(graphic)
-
+
+ def addSymbolWindow(self):
+ from utils.custom import ShapeDialog
+ ShapeDialog(self).exec()
+
def newProject(self):
#call to create a new file inside mdi area
project = FileWindow(self.mdi)
diff --git a/src/main/python/utils/custom.py b/src/main/python/utils/custom.py
new file mode 100644
index 0000000..c21017e
--- /dev/null
+++ b/src/main/python/utils/custom.py
@@ -0,0 +1,236 @@
+from PyQt5.QtCore import QRectF, Qt
+from PyQt5.QtGui import (
+ QBrush, QImage, QPainter, QPainterPath, QPen, QPixmap, QTransform)
+from PyQt5.QtSvg import QGraphicsSvgItem
+from PyQt5.QtWidgets import (QBoxLayout, QDialog, QFileDialog,
+ QGraphicsEllipseItem, QGraphicsItem,
+ QGraphicsScene, QGraphicsView, QGridLayout,
+ QLabel, QLineEdit, QPushButton, QInputDialog, QTextEdit)
+
+from shapes import SizeGripItem, directionsEnum
+
+from .app import fileImporter
+
+class ShapeDialog(QDialog):
+
+ def __init__(self, parent=None):
+ super(ShapeDialog, self).__init__(parent)
+ self.resize(500, 300)
+ self.setWindowTitle("Add New Shapes")
+ self.createLayout()
+ self.graphic = None
+
+ def createLayout(self):
+ importButton = QPushButton("Import", self)
+ importButton.clicked.connect(self.importSVG)
+
+ saveButton = QPushButton("Save", self)
+ saveButton.clicked.connect(self.saveEvent)
+
+ self.symbolName = QLineEdit(self)
+ self.symbolName.setPlaceholderText("Enter Symbol Name")
+ symbolNameLabel = QLabel("Symbol Name")
+ symbolNameLabel.setBuddy(self.symbolName)
+
+ self.symbolClass = QLineEdit(self)
+ self.symbolClass.setPlaceholderText("Enter Symbol Class Name")
+ symbolClassLabel = QLabel("Symbol Class Name")
+ symbolClassLabel.setBuddy(self.symbolClass)
+
+ self.symbolCategory = QLineEdit(self)
+ self.symbolCategory.setPlaceholderText("Enter Symbol Category")
+ symbolCategoryLabel = QLabel("Symbol Category")
+ symbolCategoryLabel.setBuddy(self.symbolCategory)
+
+ addGripItem = QPushButton("Add Grip Item", self)
+ addGripItem.clicked.connect(self.addGrip)
+ addLineGripItem = QPushButton("Add Line Grip Item", self)
+ addLineGripItem.clicked.connect(self.addLineGrip)
+
+ self.painter = QGraphicsScene()
+ view = QGraphicsView(self.painter)
+
+ layout = QGridLayout(self)
+
+ subLayout = QBoxLayout(QBoxLayout.LeftToRight)
+ subLayout.addWidget(importButton)
+ subLayout.addWidget(saveButton)
+ subLayout.addStretch(1)
+
+ layout.addLayout(subLayout, 0, 0, 1, -1)
+
+ subLayout2 = QBoxLayout(QBoxLayout.LeftToRight)
+ subLayout2.addWidget(view, stretch=1)
+
+ subLayout3 = QBoxLayout(QBoxLayout.TopToBottom)
+ subLayout3.addWidget(symbolNameLabel)
+ subLayout3.addWidget(self.symbolName)
+ subLayout3.addWidget(symbolClassLabel)
+ subLayout3.addWidget(self.symbolClass)
+ subLayout3.addWidget(symbolCategoryLabel)
+ subLayout3.addWidget(self.symbolCategory)
+ subLayout3.addStretch(1)
+ subLayout3.addWidget(addGripItem)
+ subLayout3.addWidget(addLineGripItem)
+ subLayout2.addLayout(subLayout3)
+
+ layout.addLayout(subLayout2, 1, 0, -1, -1)
+ self.setLayout(layout)
+
+ def importSVG(self):
+ name = QFileDialog.getOpenFileName(self, 'Open SVG File', '', 'Scalable Vector Graphics (*svg)')
+ if name:
+ self.graphic = QGraphicsSvgItem(name[0])
+ self.graphic.setZValue(-1)
+ self.painter.addItem(self.graphic)
+
+ def saveEvent(self):
+ if self.graphic is None:
+ return
+
+ itemName = self.symbolName.text()
+ if itemName is '':
+ return
+
+ className = self.symbolClass.text()
+ if className is '':
+ return
+
+ category = self.symbolCategory.text()
+ if category == "":
+ category = "misc"
+
+ graphicRect = self.graphic.boundingRect()
+
+ image = QImage(64, 64, QImage.Format_ARGB32)
+ printer = QPainter(image)
+ self.graphic.renderer().render(printer, graphicRect)
+ printer.end()
+
+ #save file
+ name = QFileDialog.getSaveFileName(self, 'Save Icon', className, 'PNG (*.png)')
+ if name:
+ image.save(name[0], "PNG")
+ else:
+ return
+
+ gripList = []
+ x, y, w, h = graphicRect.getRect()
+ for i in self.grips:
+ pos = i.pos()
+ entry = [abs((x-pos.x())/w), abs((y-pos.y())/h), i.location]
+ if isinstance(i, gripRect):
+ if i.location in ["top", "bottom"]:
+ entry.append(h)
+ else:
+ entry.append(w)
+ gripList.append(entry)
+
+ temp = QDialog(self)
+ tempLayout = QBoxLayout(QBoxLayout.TopToBottom)
+ output = OutputBox(temp, f"""
+ class {className}(NodeItem):
+ def __init__(self):
+ super({className}, self).__init__("svg/{category}/{name[0]}")
+ self.grips = {gripList}
+ """)
+ tempLayout.addWidget(output)
+ temp.setLayout(tempLayout)
+ temp.exec()
+
+ @property
+ def grips(self):
+ return [i for i in self.painter.items() if isinstance(i, gripAbstract)]
+
+ def addGrip(self):
+ grip = gripDot()
+ self.painter.addItem(grip)
+
+ def addLineGrip(self):
+ rect = gripRect()
+ self.painter.addItem(rect)
+
+class gripAbstract(QGraphicsItem):
+
+ def __init__(self):
+ super(gripAbstract, self).__init__()
+ self.location = "top"
+ self.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable)
+
+ def mouseDoubleClickEvent(self, event):
+ self.location, _ = QInputDialog.getItem(None, "Change location", "Select location", directionsEnum,
+ directionsEnum.index(self.location), False)
+
+class gripRect(gripAbstract):
+ def __init__(self, x=0, y=0, w=80, h=10 ):
+ super(gripRect, self).__init__()
+ self.rotation = 0
+ self.sizeGripItems = []
+ self.width = w
+ self.height = h
+ self.setFlag(QGraphicsItem.ItemSendsGeometryChanges)
+
+ def boundingRect(self):
+ return QRectF(-self.width / 2, -self.height / 2, self.width, self.height)
+
+ def paint(self, painter, option, index):
+ painter.setPen(QPen(Qt.black, 1, Qt.SolidLine))
+ painter.setBrush(QBrush(Qt.red))
+ painter.drawRect(self.boundingRect())
+
+ def addGripItems(self):
+ for i, (direction) in enumerate((Qt.Vertical,
+ Qt.Horizontal,
+ Qt.Vertical,
+ Qt.Horizontal)):
+ self.sizeGripItems.append(SizeGripItem(i, direction, parent=self))
+
+ def updateSizeGripItem(self, index_no_updates=None):
+ index_no_updates = index_no_updates or []
+ for i, item in enumerate(self.sizeGripItems):
+ if i not in index_no_updates:
+ item.updatePosition()
+
+ def itemChange(self, change, value):
+ if change == QGraphicsItem.ItemPositionHasChanged:
+ # update grips
+ self.updateSizeGripItem()
+ return
+ # check if item is add on scene
+ if change == QGraphicsItem.ItemSceneHasChanged and self.scene():
+ # add grips and update them
+ self.addGripItems()
+ self.updateSizeGripItem()
+ return
+ return super(gripRect, self).itemChange(change, value)
+
+ def resize(self, index, movement):
+ self.prepareGeometryChange()
+ if index in [0, 1]:
+ self.width -= movement.x()
+ self.height -= movement.y()
+ else:
+ self.width += movement.x()
+ self.height += movement.y()
+ transform = QTransform()
+ transform.translate(movement.x() / 2, movement.y() / 2)
+ self.setTransform(transform, True)
+ self.updateSizeGripItem([index])
+
+class gripDot(gripAbstract):
+ def boundingRect(self):
+ return QRectF(0, 0, 10, 10)
+
+ def paint(self, painter, option, index):
+ painter.setPen(QPen(Qt.black, 1, Qt.SolidLine))
+ painter.setBrush(QBrush(Qt.red))
+ painter.drawEllipse(self.boundingRect())
+
+class OutputBox(QTextEdit):
+
+ def __init__(self, parent, text):
+ super(OutputBox, self).__init__(parent)
+ self.setReadOnly(True)
+ self.resize(600, 300)
+ self.text = text
+ self.setMarkdown("```python\n"+text+"\n```")
\ No newline at end of file
--
cgit
From 4911198e0e84aca58ca2fbe468415e6e98928e48 Mon Sep 17 00:00:00 2001
From: Blaine
Date: Sat, 20 Jun 2020 03:09:27 +0530
Subject: create build script
---
build.py | 13 +++++++++++++
1 file changed, 13 insertions(+)
create mode 100644 build.py
diff --git a/build.py b/build.py
new file mode 100644
index 0000000..9b5a543
--- /dev/null
+++ b/build.py
@@ -0,0 +1,13 @@
+from fbs.cmdline import command
+from os.path import dirname
+import subprocess
+
+import fbs.cmdline
+
+@command
+def compileResources():
+ subprocess.call("pyrcc5 -o src/main/python/resources/resources.py src/main/ui/resources.rcc", shell=True)
+
+if __name__ == '__main__':
+ project_dir = dirname(__file__)
+ fbs.cmdline.main(project_dir)
\ No newline at end of file
--
cgit
From 85e80194d39f8059f90da32ffba2760a46db56a8 Mon Sep 17 00:00:00 2001
From: Blaine
Date: Sat, 20 Jun 2020 03:09:52 +0530
Subject: migrate requirements to requirements/base
---
requirements.txt | 2 --
requirements/base.txt | 3 +++
2 files changed, 3 insertions(+), 2 deletions(-)
delete mode 100644 requirements.txt
create mode 100644 requirements/base.txt
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index 0c683ba..0000000
--- a/requirements.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-PyQt5
-fbs
diff --git a/requirements/base.txt b/requirements/base.txt
new file mode 100644
index 0000000..2800691
--- /dev/null
+++ b/requirements/base.txt
@@ -0,0 +1,3 @@
+PyQt5
+fbs
+qstylizer
\ No newline at end of file
--
cgit
From d6946c9a3659eae563e33b3d5ac3aa026cf5b75a Mon Sep 17 00:00:00 2001
From: Blaine
Date: Sat, 20 Jun 2020 03:10:28 +0530
Subject: use Qresource to implement close icon
---
src/main/python/resources/__init__.py | 0
src/main/python/resources/resources.py | 65 +++++++++++++++++++++++++++++++++
src/main/python/utils/app.py | 4 +-
src/main/resources/base/app.qss | 8 ++--
src/main/resources/base/ui/close.png | Bin 255 -> 0 bytes
src/main/ui/close.png | Bin 0 -> 255 bytes
src/main/ui/resources.rcc | 5 +++
7 files changed, 78 insertions(+), 4 deletions(-)
create mode 100644 src/main/python/resources/__init__.py
create mode 100644 src/main/python/resources/resources.py
delete mode 100644 src/main/resources/base/ui/close.png
create mode 100644 src/main/ui/close.png
create mode 100644 src/main/ui/resources.rcc
diff --git a/src/main/python/resources/__init__.py b/src/main/python/resources/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/src/main/python/resources/resources.py b/src/main/python/resources/resources.py
new file mode 100644
index 0000000..51952b7
--- /dev/null
+++ b/src/main/python/resources/resources.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+
+# Resource object code
+#
+# Created by: The Resource Compiler for PyQt5 (Qt v5.15.0)
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt5 import QtCore
+
+qt_resource_data = b"\
+\x00\x00\x00\xff\
+\x89\
+\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
+\x00\x00\x0e\x00\x00\x00\x0e\x08\x06\x00\x00\x00\x1f\x48\x2d\xd1\
+\x00\x00\x00\x06\x62\x4b\x47\x44\x00\x00\x00\x00\x00\x00\xf9\x43\
+\xbb\x7f\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\
+\x0b\x13\x01\x00\x9a\x9c\x18\x00\x00\x00\x07\x74\x49\x4d\x45\x07\
+\xdf\x06\x09\x0b\x33\x34\x04\x7e\xc0\x14\x00\x00\x00\x1d\x69\x54\
+\x58\x74\x43\x6f\x6d\x6d\x65\x6e\x74\x00\x00\x00\x00\x00\x43\x72\
+\x65\x61\x74\x65\x64\x20\x77\x69\x74\x68\x20\x47\x49\x4d\x50\x64\
+\x2e\x65\x07\x00\x00\x00\x63\x49\x44\x41\x54\x28\x53\x63\x60\x18\
+\x48\xe0\x03\xb4\x1c\x84\x71\x01\x14\x79\x26\x2c\xaa\xb0\x69\xc6\
+\x10\x63\x44\xd3\x88\xac\x60\x0b\x54\x0e\x9b\x18\x03\xba\x46\x90\
+\x5a\x0c\xd3\xa1\x06\xc0\x0c\x02\x73\xb1\x69\xc4\xa6\x19\x45\x13\
+\x48\x01\x36\x3f\x42\x2d\xc0\x4f\x61\xb3\x91\x2c\xa7\x62\x0b\x08\
+\x6c\x62\x28\x7e\xc4\xaa\x00\xea\x60\x0c\x39\x6c\x7e\xc4\x08\x08\
+\xa0\x66\x6c\x62\xf8\x03\x81\xea\xb2\x00\xa1\x91\x0c\x3d\x2a\x6a\
+\x45\xe6\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
+"
+
+qt_resource_name = b"\
+\x00\x09\
+\x06\x99\x2e\x3e\
+\x00\x63\
+\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x49\x00\x63\x00\x6f\x00\x6e\
+"
+
+qt_resource_struct_v1 = b"\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
+"
+
+qt_resource_struct_v2 = b"\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
+\x00\x00\x01\x72\xa2\x8c\x44\x86\
+"
+
+qt_version = [int(v) for v in QtCore.qVersion().split('.')]
+if qt_version < [5, 8, 0]:
+ rcc_version = 1
+ qt_resource_struct = qt_resource_struct_v1
+else:
+ rcc_version = 2
+ qt_resource_struct = qt_resource_struct_v2
+
+def qInitResources():
+ QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+def qCleanupResources():
+ QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+qInitResources()
diff --git a/src/main/python/utils/app.py b/src/main/python/utils/app.py
index 60ae47f..275ef7e 100644
--- a/src/main/python/utils/app.py
+++ b/src/main/python/utils/app.py
@@ -3,12 +3,14 @@ Declare fbs application so that it can be imported in other modules.
"""
from fbs_runtime.application_context.PyQt5 import ApplicationContext
-from PyQt5.QtCore import QSettings, pyqtProperty
+from PyQt5.QtCore import QSettings, pyqtProperty, QResource
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QWidget
from json import JSONEncoder, dumps, loads, dump, load
from os.path import join
+from resources import resources
+
app = ApplicationContext()
settings = QSettings(QSettings.IniFormat, QSettings.UserScope ,"FOSSEE", "Chemical-PFD")
version = app.build_settings['version']
diff --git a/src/main/resources/base/app.qss b/src/main/resources/base/app.qss
index 866d977..cd11034 100644
--- a/src/main/resources/base/app.qss
+++ b/src/main/resources/base/app.qss
@@ -38,7 +38,7 @@ QLineEdit:focus{
border-color: #7cabf9;
}
TabBarPlus {
- /* qpropery-drawBase: 0; */
+ qproperty-drawBase: 0;
left: 5px;
background-color: transparent;
font-size: 15px;
@@ -49,6 +49,7 @@ TabBarPlus:focus {
}
TabBarPlus::close-button {
+ background-image: url(:/closeIcon);
padding: 0px;
margin: 0px;
border-radius: 2px;
@@ -260,9 +261,10 @@ CustomTabWidget CustomView {
padding: 5px;
border-radius: 2px;
}
-/* QHeaderView {
+
+QHeaderView {
qproperty-defaultAlignment: AlignHCenter;
-} */
+}
QHeaderView::section {
padding: 4px;
diff --git a/src/main/resources/base/ui/close.png b/src/main/resources/base/ui/close.png
deleted file mode 100644
index 8771a0b..0000000
Binary files a/src/main/resources/base/ui/close.png and /dev/null differ
diff --git a/src/main/ui/close.png b/src/main/ui/close.png
new file mode 100644
index 0000000..8771a0b
Binary files /dev/null and b/src/main/ui/close.png differ
diff --git a/src/main/ui/resources.rcc b/src/main/ui/resources.rcc
new file mode 100644
index 0000000..b7dcdfc
--- /dev/null
+++ b/src/main/ui/resources.rcc
@@ -0,0 +1,5 @@
+
+class {className}(NodeItem): + def __init__(self): + super({className}, self).__init__("svg/{category}/{str.split(name[0], "/")[-1][:-4]}") + {grips} ++ Items.json entry: +
+"{category}": {{ + "{itemName}": {{ + "name": "{itemName}", + "icon": ".\\{category}\\{str.split(name[0], "/")[-1]}", + "class": "{category}", + "object": "{className}", + "args": [] + }} +}}""") tempLayout.addWidget(output) temp.setLayout(tempLayout) temp.exec() @@ -229,6 +247,5 @@ class OutputBox(QTextEdit): def __init__(self, parent, text): super(OutputBox, self).__init__(parent) self.setReadOnly(True) - self.resize(600, 300) - self.text = text - self.setMarkdown("```python\n"+text+"\n```") + self.setFontWeight(10) + self.setHtml(text) \ No newline at end of file -- cgit From f8519766d7f7fc70180411f912ed8ca15abb6a95 Mon Sep 17 00:00:00 2001 From: Blaine Date: Sat, 20 Jun 2020 14:43:57 +0530 Subject: refactor and comment code --- src/main/python/main.py | 63 +++++++++++++++-------------- src/main/python/shapes/shapes.py | 3 ++ src/main/python/utils/app.py | 18 +++++---- src/main/python/utils/canvas.py | 25 +++++++----- src/main/python/utils/custom.py | 64 +++++++++++++++++++++++------ src/main/python/utils/dialogs.py | 1 + src/main/python/utils/fileWindow.py | 13 +++--- src/main/python/utils/graphics.py | 8 ---- src/main/python/utils/layout.py | 16 ++++++++ src/main/python/utils/streamTable.py | 78 +++++++++++++++++++++++++----------- src/main/python/utils/tabs.py | 3 +- src/main/python/utils/toolbar.py | 2 - src/main/python/utils/undo.py | 1 + 13 files changed, 192 insertions(+), 103 deletions(-) diff --git a/src/main/python/main.py b/src/main/python/main.py index db938b5..35c95c3 100644 --- a/src/main/python/main.py +++ b/src/main/python/main.py @@ -25,8 +25,30 @@ class appWindow(QMainWindow): super(appWindow, self).__init__(parent) #create the menu bar + self.createMenuBar() + + self.mdi = QMdiArea(self) #create area for files to be displayed + self.mdi.setObjectName('mdi area') + + #create toolbar and add the toolbar plus mdi to layout + self.createToolbar() + + #set flags so that window doesnt look weird + self.mdi.setOption(QMdiArea.DontMaximizeSubWindowOnActivation, True) + self.mdi.setTabsClosable(True) + self.mdi.setTabsMovable(True) + self.mdi.setDocumentMode(False) + + #declare main window layout + self.setCentralWidget(self.mdi) + # self.resize(1280, 720) #set collapse dim + self.mdi.subWindowActivated.connect(self.tabSwitched) + self.readSettings() + + def createMenuBar(self): + # Fetches a reference to the menu bar in the main window, and adds actions to it. + titleMenu = self.menuBar() #fetch reference to current menu bar - # self.mainWidget.setObjectName("Main Widget") self.menuFile = titleMenu.addMenu('File') #File Menu newAction = self.menuFile.addAction("New", self.newProject) @@ -54,25 +76,7 @@ class appWindow(QMainWindow): imageAction.setShortcut(QKeySequence("Ctrl+P")) reportAction.setShortcut(QKeySequence("Ctrl+R")) - - self.mdi = QMdiArea(self) #create area for files to be displayed - self.mdi.setObjectName('mdi area') - - #create toolbar and add the toolbar plus mdi to layout - self.createToolbar() - - #set flags so that window doesnt look weird - self.mdi.setOption(QMdiArea.DontMaximizeSubWindowOnActivation, True) - self.mdi.setTabsClosable(True) - self.mdi.setTabsMovable(True) - self.mdi.setDocumentMode(False) - - #declare main window layout - self.setCentralWidget(self.mdi) - # self.resize(1280, 720) #set collapse dim - self.mdi.subWindowActivated.connect(self.tabSwitched) - self.readSettings() - + def createToolbar(self): #place holder for toolbar with fixed width, layout may change self.toolbar = toolbar(self) @@ -83,16 +87,16 @@ class appWindow(QMainWindow): self.toolbar.populateToolbar() def toolButtonClicked(self, object): + # To add the corresponding symbol for the clicked button to active scene. if self.mdi.currentSubWindow(): currentDiagram = self.mdi.currentSubWindow().tabber.currentWidget().painter if currentDiagram: graphic = getattr(shapes, object['object'])(*map(lambda x: int(x) if x.isdigit() else x, object['args'])) - # graphic.setPen(QPen(Qt.black, 2)) - # graphic.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable) - graphic.setPos(20, 20) + graphic.setPos(50, 50) currentDiagram.addItemPlus(graphic) def addSymbolWindow(self): + # Opens the add symbol window when requested from utils.custom import ShapeDialog ShapeDialog(self).exec() @@ -103,7 +107,6 @@ class appWindow(QMainWindow): self.mdi.addSubWindow(project) if not project.tabList: # important when unpickling a file instead project.newDiagram() #create a new tab in the new file - # project.resizeHandler() project.fileCloseEvent.connect(self.fileClosed) #closed file signal to switch to sub window view if self.count > 1: #switch to tab view if needed self.mdi.setViewMode(QMdiArea.TabbedView) @@ -118,6 +121,7 @@ class appWindow(QMainWindow): projectData = load(file) project = FileWindow(self.mdi) self.mdi.addSubWindow(project) + #create blank window and set its state project.__setstate__(projectData) project.resizeHandler() project.fileCloseEvent.connect(self.fileClosed) @@ -127,7 +131,7 @@ class appWindow(QMainWindow): self.mdi.setViewMode(QMdiArea.TabbedView) def saveProject(self): - #pickle all files in mdi area + #serialize all files in mdi area for j, i in enumerate(self.activeFiles): #get list of all windows with atleast one tab if i.tabCount: name = QFileDialog.getSaveFileName(self, 'Save File', f'New Diagram {j}', 'Process Flow Diagram (*.pfd)') @@ -170,6 +174,7 @@ class appWindow(QMainWindow): self.mdi.setViewMode(QMdiArea.SubWindowView) def writeSettings(self): + # write window state on window close settings.beginGroup("MainWindow") settings.setValue("maximized", self.isMaximized()) if not self.isMaximized(): @@ -178,6 +183,7 @@ class appWindow(QMainWindow): settings.endGroup() def readSettings(self): + # read window state when app launches settings.beginGroup("MainWindow") self.resize(settings.value("size", QSize(1280, 720))) self.move(settings.value("pos", QPoint(320, 124))) @@ -185,6 +191,7 @@ class appWindow(QMainWindow): self.showMaximized() settings.endGroup() + #useful one liner properties for getting data @property def activeFiles(self): return [i for i in self.mdi.subWindowList() if i.tabCount] @@ -219,11 +226,9 @@ class appWindow(QMainWindow): if self.mdi.activeSubWindow() and self.mdi.activeSubWindow().tabber.currentWidget(): for item in self.mdi.activeSubWindow().tabber.currentWidget().painter.selectedItems(): item.rotation += 1 - - - + if __name__ == '__main__': # 1. Instantiate ApplicationContext main = appWindow() main.show() - exit_code = app.app.exec_() # 2. Invoke appctxt.app.exec_() + exit_code = app.app.exec_() # 2. Invoke app.app.exec_() sys.exit(exit_code) diff --git a/src/main/python/shapes/shapes.py b/src/main/python/shapes/shapes.py index ca6490c..5876f6e 100644 --- a/src/main/python/shapes/shapes.py +++ b/src/main/python/shapes/shapes.py @@ -12,6 +12,7 @@ from PyQt5.QtWidgets import (QGraphicsColorizeEffect, QGraphicsEllipseItem, from .line import Line, findIndex from utils.app import fileImporter +# enum for all directions for line grip items directionsEnum = [ "top", "right", @@ -19,6 +20,7 @@ directionsEnum = [ "left" ] +# orientation enum for size grip items orientationEnum = [ Qt.Horizontal, Qt.Vertical @@ -469,6 +471,7 @@ class NodeItem(QGraphicsSvgItem): return self.flipState[1] def updateTransformation(self): + # update transformation on flipstate or rotation change transform = QTransform() h = -1 if self.flipH else 1 w = -1 if self.flipV else 1 diff --git a/src/main/python/utils/app.py b/src/main/python/utils/app.py index 275ef7e..39c3674 100644 --- a/src/main/python/utils/app.py +++ b/src/main/python/utils/app.py @@ -1,5 +1,5 @@ """ -Declare fbs application so that it can be imported in other modules. +Declare fbs application and various contextual variables so that it can be imported in other modules. """ from fbs_runtime.application_context.PyQt5 import ApplicationContext @@ -9,7 +9,7 @@ from PyQt5.QtWidgets import QWidget from json import JSONEncoder, dumps, loads, dump, load from os.path import join -from resources import resources +from resources import resources #application resources defined in resources.qrc app = ApplicationContext() settings = QSettings(QSettings.IniFormat, QSettings.UserScope ,"FOSSEE", "Chemical-PFD") @@ -19,11 +19,14 @@ def fileImporter(*file): # Helper function to fetch files from src/main/resources return app.get_resource(join(*file)) +#set application stylesheet with open(fileImporter("app.qss"), "r") as stylesheet: app.app.setStyleSheet(stylesheet.read()) class JSON_Encoder: - + """ + Defines serialization methods for differnt data types for json module + """ def _encode(obj): if isinstance(obj, dict): ## We'll need to iterate not just the value that default() usually gets passed @@ -50,7 +53,9 @@ class JSON_Encoder: return obj class JSON_Typer(JSONEncoder): - + """ + derived class for redirecting encode calls + """ def default(self, o): return o.__getstate__() @@ -60,7 +65,4 @@ class JSON_Typer(JSONEncoder): def encode(self, obj): return super(JSON_Typer, self).encode(self._encode(obj)) - -importer = pyqtProperty(str, fileImporter) - -memMap = {} \ No newline at end of file +memMap = {} #memory map for id references for loading projects \ No newline at end of file diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py index 8608f7b..68b0902 100644 --- a/src/main/python/utils/canvas.py +++ b/src/main/python/utils/canvas.py @@ -42,6 +42,9 @@ class canvas(CustomView): self.customContextMenuRequested.connect(self.sideViewContextMenu) def addStreamTable(self, pos=QPointF(0, 0), table=None): + """ + build stream table at pos with table, if table is not passed, builds a blank table + """ self.streamTable = table if table else streamTable(self.labelItems, canvas=self) self.streamTableRect = moveRect() @@ -53,10 +56,16 @@ class canvas(CustomView): self.streamTableRect.setPos(pos) def updateStreamTable(self, item): + """ + updates stream table with any new line labels added + """ if self.streamTable: self.streamTable.model.insertColumn(item = item) def sideViewContextMenu(self, pos): + """ + shows the context menu for the side view + """ self.parentFileWindow.sideViewContextMenu(self.mapTo(self.parentFileWindow, pos)) def resizeView(self, w, h): @@ -69,11 +78,6 @@ class canvas(CustomView): frameWidth = self.frameWidth() #update view size self.setSceneRect(0, 0, width - frameWidth*2, height) - - def resizeEvent(self, event): - #overloaded function to also view size on window update - # self.adjustView() - pass def setCanvasSize(self, size): """ @@ -152,6 +156,7 @@ class canvas(CustomView): self.landscape = dict['landscape'] self.setObjectName(dict['ObjectName']) + #load symbols from the file, while building the memory map as well. for item in dict['symbols']: graphic = getattr(shapes, item['_classname_'])() graphic.__setstate__(dict = item) @@ -168,6 +173,7 @@ class canvas(CustomView): graphic.rotation = item['rotation'] graphic.flipH, graphic.flipV = item['flipstate'] + #load lines from the file, while using and building the memory map. for item in dict['lines']: line = shapes.Line(QPointF(*item['startPoint']), QPointF(*item['endPoint'])) memMap[item['id']] = line @@ -192,14 +198,11 @@ class canvas(CustomView): line.updateLine() line.addGrabber() + # add streamtable if it existed in the scene. if dict['streamTable']: table = streamTable(self.labelItems, self) self.addStreamTable(QPointF(*dict['streamTable'][1]), table) table.__setstate__(dict['streamTable'][0]) - memMap.clear() - self.painter.advance() - - - - \ No newline at end of file + memMap.clear() #clear out memory map as we now have no use for it. Hopefully garbage collected + self.painter.advance() #request collision detection \ No newline at end of file diff --git a/src/main/python/utils/custom.py b/src/main/python/utils/custom.py index 7e6b197..fedecdb 100644 --- a/src/main/python/utils/custom.py +++ b/src/main/python/utils/custom.py @@ -1,3 +1,6 @@ +""" +Holds the custom window to generate new symbols, can be called while running or throught the build interface. +""" from PyQt5.QtCore import QRectF, Qt, QSize from PyQt5.QtGui import (QBrush, QIcon, QImage, QPainter, QPainterPath, QPen, QPixmap, QTransform) @@ -12,17 +15,19 @@ from shapes import SizeGripItem, directionsEnum from .app import fileImporter - class ShapeDialog(QDialog): - + """ + The main dialog box for the custom symbol window. + """ def __init__(self, parent=None): super(ShapeDialog, self).__init__(parent) - self.resize(500, 300) + self.resize(500, 300) # resize to a fixed dim self.setWindowTitle("Add New Shapes") self.createLayout() self.graphic = None def createLayout(self): + #build layout for the dialog box importButton = QPushButton("Import", self) importButton.clicked.connect(self.importSVG) @@ -80,6 +85,7 @@ class ShapeDialog(QDialog): self.setLayout(layout) def importSVG(self): + # Imports svg file through user input, adds it to the scene and stores it as a reference self.name = QFileDialog.getOpenFileName(self, 'Open SVG File', '', 'Scalable Vector Graphics (*svg)') if self.name: self.graphic = QGraphicsSvgItem(self.name[0]) @@ -87,6 +93,9 @@ class ShapeDialog(QDialog): self.painter.addItem(self.graphic) def saveEvent(self): + # executes the build procedure + + #check if all necessary values are there, each is seperate to show qalerts later on if self.graphic is None: return @@ -102,10 +111,9 @@ class ShapeDialog(QDialog): if category == "": category = "misc" + # get rect for calculating grip positions graphicRect = self.graphic.boundingRect() - - QIcon - + #save file name = QFileDialog.getSaveFileName(self, 'Save Icon', className, 'PNG (*.png)') if name: @@ -113,6 +121,7 @@ class ShapeDialog(QDialog): else: return + #calculate grip positions and build a list gripList = [] x, y, w, h = graphicRect.getRect() for i in self.grips: @@ -125,10 +134,12 @@ class ShapeDialog(QDialog): entry.append(i.width) gripList.append(entry) - + # format list in class definition flavor grips = ",\n ".join([str(i) for i in gripList]) if gripList else "" if grips: grips = "self.grips = [" + grips + "]\n" + + # build output dialog box temp = QDialog(self) tempLayout = QBoxLayout(QBoxLayout.TopToBottom) output = OutputBox(temp, f""" @@ -159,15 +170,19 @@ class {className}(NodeItem): return [i for i in self.painter.items() if isinstance(i, gripAbstract)] def addGrip(self): + #adds a grip dot to the scene grip = gripDot() self.painter.addItem(grip) def addLineGrip(self): + #adds a line grip item rect = gripRect() self.painter.addItem(rect) class gripAbstract(QGraphicsItem): - + """ + Abstract class for mouse click behaviour + """ def __init__(self): super(gripAbstract, self).__init__() self.location = "top" @@ -178,6 +193,10 @@ class gripAbstract(QGraphicsItem): directionsEnum.index(self.location), False) class gripRect(gripAbstract): + """ + simulates line grip item with resizeablity + (Haha grip items on grip items. Progress) + """ def __init__(self, x=0, y=0, w=80, h=10 ): super(gripRect, self).__init__() self.rotation = 0 @@ -185,7 +204,8 @@ class gripRect(gripAbstract): self.width = w self.height = h self.setFlag(QGraphicsItem.ItemSendsGeometryChanges) - + + #bounding rect and paint need to be implemented def boundingRect(self): return QRectF(-self.width / 2, -self.height / 2, self.width, self.height) @@ -193,8 +213,9 @@ class gripRect(gripAbstract): painter.setPen(QPen(Qt.black, 1, Qt.SolidLine)) painter.setBrush(QBrush(Qt.red)) painter.drawRect(self.boundingRect()) - + def addGripItems(self): + # adds the resizeable line grip items from the shape file :D for i, (direction) in enumerate((Qt.Vertical, Qt.Horizontal, Qt.Vertical, @@ -202,12 +223,14 @@ class gripRect(gripAbstract): self.sizeGripItems.append(SizeGripItem(i, direction, parent=self)) def updateSizeGripItem(self, index_no_updates=None): + #update positions for existing grip items index_no_updates = index_no_updates or [] for i, item in enumerate(self.sizeGripItems): if i not in index_no_updates: item.updatePosition() def itemChange(self, change, value): + #do the needful when item is updated if change == QGraphicsItem.ItemPositionHasChanged: # update grips self.updateSizeGripItem() @@ -221,6 +244,7 @@ class gripRect(gripAbstract): return super(gripRect, self).itemChange(change, value) def resize(self, index, movement): + #resize method self.prepareGeometryChange() if index in [0, 1]: self.width -= movement.x() @@ -233,7 +257,10 @@ class gripRect(gripAbstract): self.setTransform(transform, True) self.updateSizeGripItem([index]) -class gripDot(gripAbstract): +class gripDot(gripAbstract): + """ + class for circular grips + """ def boundingRect(self): return QRectF(0, 0, 10, 10) @@ -243,9 +270,20 @@ class gripDot(gripAbstract): painter.drawEllipse(self.boundingRect()) class OutputBox(QTextEdit): - + """ + Defines a read only text box for class output + """ def __init__(self, parent, text): super(OutputBox, self).__init__(parent) self.setReadOnly(True) self.setFontWeight(10) - self.setHtml(text) \ No newline at end of file + self.setHtml(text) + +if __name__ == '__main__': # 1. Instantiate ApplicationContext + #if app is launched directly + from .app import app + import sys + main = ShapeDialog() + main.show() + exit_code = app.app.exec_() # 2. Invoke app.app.exec_() + sys.exit(exit_code) \ No newline at end of file diff --git a/src/main/python/utils/dialogs.py b/src/main/python/utils/dialogs.py index f2c4eb9..043597c 100644 --- a/src/main/python/utils/dialogs.py +++ b/src/main/python/utils/dialogs.py @@ -110,6 +110,7 @@ def saveEvent(parent = None): return True def showUndoDialog(undoView, parent): + # helper function to show a dialog box containing the undo view dialogBox = QDialog(parent) dialogBox.resize(400, 400) layout = QHBoxLayout(dialogBox) diff --git a/src/main/python/utils/fileWindow.py b/src/main/python/utils/fileWindow.py index b2f5304..7ea5619 100644 --- a/src/main/python/utils/fileWindow.py +++ b/src/main/python/utils/fileWindow.py @@ -39,6 +39,7 @@ class FileWindow(QMdiSubWindow): layout = QHBoxLayout(self.mainWidget) self.createSideViewArea() #create the side view objects + # set size policies for window left = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) left.setHorizontalStretch(1) self.tabber.setSizePolicy(left) @@ -47,8 +48,8 @@ class FileWindow(QMdiSubWindow): right.setHorizontalStretch(1) self.sideView.setSizePolicy(right) + #build widget layout layout.addWidget(self.tabber) - # layout.addWidget(self.splitter) layout.addWidget(self.sideView) self.mainWidget.setLayout(layout) self.setWidget(self.mainWidget) @@ -66,7 +67,6 @@ class FileWindow(QMdiSubWindow): def createSideViewArea(self): #creates the side view widgets and sets them to invisible - # self.splitter = QSplitter(Qt.Vertical ,self) self.sideView = CustomView(parent = self) self.sideView.setInteractive(False) self.sideViewCloseButton = QPushButton('×', self.sideView) @@ -75,7 +75,6 @@ class FileWindow(QMdiSubWindow): self.sideViewCloseButton.setFixedSize(20, 20) self.moveSideViewCloseButton() self.sideViewCloseButton.clicked.connect(lambda: setattr(self, 'sideViewTab', None)) - # self.splitter.setVisible(False) self.sideView.setVisible(False) self.sideView.setContextMenuPolicy(Qt.CustomContextMenu) self.sideView.customContextMenuRequested.connect(self.sideViewContextMenu) @@ -127,13 +126,11 @@ class FileWindow(QMdiSubWindow): def sideViewToggle(self): #Function checks if current side view tab is set, and toggles view as required if self.sideViewTab: - # self.splitter.setVisible(True) self.sideView.setVisible(True) self.sideView.setScene(self.tabber.currentWidget().painter) self.resizeHandler() return True - else: - # self.splitter.setVisible(False) + else: self.sideView.setVisible(False) self.resizeHandler() return False @@ -163,6 +160,7 @@ class FileWindow(QMdiSubWindow): menu.exec_(self.sideView.mapToGlobal(point)) def sideViewSwitchCMenu(self, index): + # helper function to swtich side view tab self.sideViewTab = self.tabber.widget(index) def sideViewSwitchTab(self): @@ -234,8 +232,7 @@ class FileWindow(QMdiSubWindow): else: event.ignore() - #following 2 methods are defined for correct pickling of the scene. may be changed to json or xml later so as - # to not have a binary file. + #following 2 methods are defined for correct serialization of the scene. def __getstate__(self) -> dict: return { "_classname_": self.__class__.__name__, diff --git a/src/main/python/utils/graphics.py b/src/main/python/utils/graphics.py index 05ffc46..bb113ce 100644 --- a/src/main/python/utils/graphics.py +++ b/src/main/python/utils/graphics.py @@ -20,12 +20,6 @@ class CustomView(QGraphicsView): self._zoom = 1 self.setDragMode(True) #sets pannable using mouse self.setAcceptDrops(True) #sets ability to accept drops - if scene: - #create necessary undo redo actions to accept keyboard shortcuts - # self.addAction(scene.undoAction) - # self.addAction(scene.redoAction) - # self.addAction(scene.deleteAction) - pass #following four functions are required to be overridden for drag-drop functionality def dragEnterEvent(self, QDragEnterEvent): @@ -48,8 +42,6 @@ class CustomView(QGraphicsView): #QDropEvent.mimeData().text() defines intended drop item, the pos values define position obj = QDropEvent.mimeData().text().split('/') graphic = getattr(shapes, obj[0])(*map(lambda x: int(x) if x.isdigit() else x, obj[1:])) - # graphic.setPen(QPen(Qt.black, 2)) - # graphic.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable) graphic.setPos(QDropEvent.pos().x(), QDropEvent.pos().y()) self.scene().addItemPlus(graphic) QDropEvent.acceptProposedAction() diff --git a/src/main/python/utils/layout.py b/src/main/python/utils/layout.py index b977a68..e1354b0 100644 --- a/src/main/python/utils/layout.py +++ b/src/main/python/utils/layout.py @@ -2,6 +2,10 @@ from PyQt5.QtCore import Qt, QRect, QPoint, QSize from PyQt5.QtWidgets import QLayout, QSizePolicy class flowLayout(QLayout): + """ + Custom layout that flows horizontally first, then vertically. + From Qt examples. + """ def __init__(self, parent=None, margin=0, spacing=12): super(flowLayout, self).__init__(parent) @@ -12,46 +16,57 @@ class flowLayout(QLayout): self.itemList = [] def __del__(self): + # Delete layout call item = self.takeAt(0) while item: item = self.takeAt(0) def addItem(self, item): + # add item to layout self.itemList.append(item) def count(self): + # return a list of items return len(self.itemList) def itemAt(self, index): + # return item at index if index >= 0 and index < len(self.itemList): return self.itemList[index] return None def takeAt(self, index): + # pop item at index if index >= 0 and index < len(self.itemList): return self.itemList.pop(index) return None def expandingDirections(self): + # define orientation return Qt.Orientations(Qt.Orientation(0)) def hasHeightForWidth(self): + # height for width flag, height value for a particular width return True def heightForWidth(self, width): + # returns the height for a given width height = self.doLayout(QRect(0, 0, width, 0), True) return height def setGeometry(self, rect): + # change layout geometry super(flowLayout, self).setGeometry(rect) self.doLayout(rect, False) def sizeHint(self): + # returns the expected size return self.minimumSize() def minimumSize(self): + # calucalate minimum possible size below which, resize is impossible size = QSize() for item in self.itemList: @@ -63,6 +78,7 @@ class flowLayout(QLayout): return size def doLayout(self, rect, testOnly): + # build layout, testOnly defines if the geometry needs to be changed or not x = rect.x() y = rect.y() lineHeight = 0 diff --git a/src/main/python/utils/streamTable.py b/src/main/python/utils/streamTable.py index c8e682c..8b3b220 100644 --- a/src/main/python/utils/streamTable.py +++ b/src/main/python/utils/streamTable.py @@ -5,13 +5,17 @@ from PyQt5.QtWidgets import QTableView, QMenu, QGraphicsRectItem, QInputDialog, from collections import defaultdict class streamTableModel(QAbstractTableModel): + """ + Defines the table model for the table view + """ updateEvent = pyqtSignal() def __init__(self, parent, list, header, *args): super(streamTableModel, self).__init__(parent, *args) self.list = list self.header = header - + + # column count, row count, data and setdata are important methods to be overloaded def columnCount(self, parent=None): return len(self.list) @@ -19,31 +23,41 @@ class streamTableModel(QAbstractTableModel): return len(self.header) def data(self, index, role): + # retunrs data at index if role == Qt.TextAlignmentRole: return Qt.AlignHCenter + if role == Qt.BackgroundColorRole: return Qt.white + if not index.isValid(): return None + elif role != Qt.DisplayRole: return None + if index.row() == 0: - return self.list[index.column()].toPlainText() + return self.list[index.column()].toPlainText() # return label name else: - return self.list[index.column()].values[self.header[index.row()]] + return self.list[index.column()].values[self.header[index.row()]] # retunr label values def setData(self, index, value, role): + # defines how to manipulate data at a given index with value returns sucess value if not index.isValid(): return False + elif role != Qt.EditRole: return False + if index.row() == 0: - self.list[index.column()].setPlainText(value) + self.list[index.column()].setPlainText(value) # change label text else: - self.list[index.column()].values[self.header[index.row()]] = value + self.list[index.column()].values[self.header[index.row()]] = value #change label values + return True def insertColumn(self, int=None, item=None): + # inserting a label item int = int if int else self.rowCount()+1 self.beginInsertColumns(QModelIndex(), int, int) self.list.insert(int, item) @@ -52,54 +66,65 @@ class streamTableModel(QAbstractTableModel): self.updateEvent.emit() def insertRow(self, int=None, name="newVal"): + # inserting a header property self.beginInsertRows(QModelIndex(), int, int) self.header.insert(int, name) self.endInsertRows() self.updateEvent.emit() def deleteRow(self, row): + # removing a property self.beginRemoveRows(QModelIndex(), row, row) - valName = self.header.pop(row) + valName = self.header.pop(row) # remove from header self.endRemoveRows() + for i in self.list: - i.values.pop(valName) - self.updateEvent.emit() + i.values.pop(valName) #clear dictionary + + self.updateEvent.emit() # update request def headerData(self, col, orientation, role): + # definds how to fetch header data if orientation == Qt.Vertical and role == Qt.DisplayRole: return self.header[col] return None def flags(self, index): + # defines item editable flag return (super(streamTableModel, self).flags(index) | Qt.ItemIsEditable) class streamTable(QTableView): - + """ + subclasses stream table to display data properly + """ def __init__(self, itemLabels=[], canvas=None, parent=None): super(streamTable, self).__init__(parent=parent) self.canvas = canvas + for i in itemLabels: - i.nameChanged.connect(self.repaint) - header = ["name", "val1", "val2", "val3", "val4", "val5"] + i.nameChanged.connect(self.repaint) # connect repaint requests on name change + + header = ["name", "val1", "val2", "val3", "val4", "val5"] # prepare header names self.model = streamTableModel(self, itemLabels, header) - self.setShowGrid(False) + self.setShowGrid(False) # disable table grid - self.horizontalHeader().hide() - header = verticalHeader(Qt.Vertical, self) + self.horizontalHeader().hide() # remove horizontal header + + header = verticalHeader(Qt.Vertical, self) #create custom vertical header self.setVerticalHeader(header) header.labelChangeRequested.connect(self.labelChange) - self.setModel(self.model) - self.borderThickness = defaultdict(lambda: False) + self.setModel(self.model) #declare model + self.borderThickness = defaultdict(lambda: False) #thickness bool dict self.model.updateEvent.connect(self.resizeHandler) self.setItemDelegateForRow(0, drawBorderDelegate(self)) - self.borderThickness[0] = True + self.borderThickness[0] = True # set border true for name row def mousePressEvent(self, event): + # handle context menu request if event.button() == Qt.RightButton: point = event.pos() - # col = self.getCol(point.x()) index = self.indexAt(point) menu = QMenu("Context Menu", self) menu.addAction("Toggle bottom border thickness", lambda x=index.row(): self.changeRowBorder(x)) @@ -110,6 +135,7 @@ class streamTable(QTableView): return super(streamTable, self).mousePressEvent(event) def changeRowBorder(self, row): + # toggle column border thicnkess if self.borderThickness[row]: self.borderThickness.pop(row) self.setItemDelegateForRow(row, QStyledItemDelegate(self)) @@ -119,6 +145,7 @@ class streamTable(QTableView): self.verticalHeader().repaint() def labelChange(self, index): + # label name change newName, bool = QInputDialog.getText(self, "Change Property Name", "Enter new name", text = self.model.header[index]) if bool: @@ -128,6 +155,7 @@ class streamTable(QTableView): self.repaint() def insertRowBottom(self, row): + # dialog box for new property name, bool = QInputDialog.getText(self, "New Property", "Enter name", text = "newVal") if bool: @@ -162,10 +190,9 @@ class streamTable(QTableView): self.repaint() class drawBorderDelegate(QStyledItemDelegate): - - # def __init__(self, parent): - # super(drawBorderDelegate, self).__init__(parent) - + """ + class for drawing border line + """ def paint(self, painter, option, index): rect = option.rect painter.drawLine(rect.bottomLeft(), rect.bottomRight()) @@ -173,7 +200,9 @@ class drawBorderDelegate(QStyledItemDelegate): super(drawBorderDelegate, self).paint(painter, option, index) class moveRect(QGraphicsRectItem): - + """ + use to move the table on the scene + """ def __init__(self, sideLength = 15, *args): super(moveRect, self).__init__(-sideLength, -sideLength, sideLength, sideLength) self.setBrush(Qt.transparent) @@ -190,6 +219,9 @@ class moveRect(QGraphicsRectItem): return super(moveRect, self).hoverLeaveEvent(event) class verticalHeader(QHeaderView): + """ + Custom Vertical header for the table, with line border against corresponding rows + """ labelChangeRequested = pyqtSignal(int) def mouseDoubleClickEvent(self, event): diff --git a/src/main/python/utils/tabs.py b/src/main/python/utils/tabs.py index cedb298..70f9def 100644 --- a/src/main/python/utils/tabs.py +++ b/src/main/python/utils/tabs.py @@ -3,7 +3,7 @@ from PyQt5.QtCore import pyqtSignal, QSize, Qt class TabBarPlus(QTabBar): """ - Just implemented to overload resize and layout change to emit a signal + Just implemented to overload resize and layout change to emit a signal and change tab names. """ layoutChanged = pyqtSignal() nameChanged = pyqtSignal(int, str) @@ -16,6 +16,7 @@ class TabBarPlus(QTabBar): self.layoutChanged.emit() def mouseDoubleClickEvent(self, event): + # tab name change request if event.button() != Qt.LeftButton: return super().mouseDoubleClickEvent() index = self.currentIndex() diff --git a/src/main/python/utils/toolbar.py b/src/main/python/utils/toolbar.py index 3f6338b..f2bbd5a 100644 --- a/src/main/python/utils/toolbar.py +++ b/src/main/python/utils/toolbar.py @@ -9,8 +9,6 @@ from .data import toolbarItems from .app import fileImporter, app from .layout import flowLayout -# resourceManager = ApplicationContext() #Used to load images, mainly toolbar icons - class toolbar(QDockWidget): """ Defines the right side toolbar, using QDockWidget. diff --git a/src/main/python/utils/undo.py b/src/main/python/utils/undo.py index 92a8de8..6a46b27 100644 --- a/src/main/python/utils/undo.py +++ b/src/main/python/utils/undo.py @@ -91,6 +91,7 @@ class moveCommand(QUndoCommand): class resizeCommand(QUndoCommand): """ + Defines the resize event for the custom scene. """ def __init__(self, new, canvas, widget, parent = None): super(resizeCommand, self).__init__(parent) -- cgit From 54c3ce344d8d4b263e6c6f98dd072293a1a74b55 Mon Sep 17 00:00:00 2001 From: Blaine Date: Sat, 20 Jun 2020 14:55:08 +0530 Subject: add build scripts --- build.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/build.py b/build.py index 9b5a543..d096792 100644 --- a/build.py +++ b/build.py @@ -3,11 +3,21 @@ from os.path import dirname import subprocess import fbs.cmdline +import fbs @command def compileResources(): subprocess.call("pyrcc5 -o src/main/python/resources/resources.py src/main/ui/resources.rcc", shell=True) +@command +def symbolGen(): + exec(open('src/main/python/utils/custom.py').read()) + +@command +def build(): + compileResources() + subprocess.call("fbs freeze", shell=True) + if __name__ == '__main__': project_dir = dirname(__file__) fbs.cmdline.main(project_dir) \ No newline at end of file -- cgit From 3a8e328002ad4c86ec0dccef1efe18ccc2742077 Mon Sep 17 00:00:00 2001 From: Blaine Date: Sat, 20 Jun 2020 15:07:20 +0530 Subject: remove qstylizer as requirement --- requirements/base.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/requirements/base.txt b/requirements/base.txt index 2800691..cd978ff 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -1,3 +1,2 @@ PyQt5 -fbs -qstylizer \ No newline at end of file +fbs \ No newline at end of file -- cgit From d67b4b853ffd4677d2a96704cb0ed5581c59c444 Mon Sep 17 00:00:00 2001 From: Blaine Date: Sat, 20 Jun 2020 15:14:30 +0530 Subject: symbol gen script --- build.py | 7 +++++-- src/main/python/utils/custom.py | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/build.py b/build.py index d096792..91a66fb 100644 --- a/build.py +++ b/build.py @@ -1,17 +1,20 @@ from fbs.cmdline import command from os.path import dirname import subprocess - +import sys import fbs.cmdline import fbs +sys.path.append('src/main/python/') + @command def compileResources(): subprocess.call("pyrcc5 -o src/main/python/resources/resources.py src/main/ui/resources.rcc", shell=True) @command def symbolGen(): - exec(open('src/main/python/utils/custom.py').read()) + from utils import custom + custom.main() @command def build(): diff --git a/src/main/python/utils/custom.py b/src/main/python/utils/custom.py index fedecdb..2c8ffc6 100644 --- a/src/main/python/utils/custom.py +++ b/src/main/python/utils/custom.py @@ -279,7 +279,7 @@ class OutputBox(QTextEdit): self.setFontWeight(10) self.setHtml(text) -if __name__ == '__main__': # 1. Instantiate ApplicationContext +def main(): # 1. Instantiate ApplicationContext #if app is launched directly from .app import app import sys -- cgit From 5afc44d63266bb1e8a57a880d64b33f95b29e3d8 Mon Sep 17 00:00:00 2001 From: Blaine Date: Sat, 20 Jun 2020 16:06:24 +0530 Subject: Add readmen --- README.md | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- requirements.txt | 2 + 2 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 requirements.txt diff --git a/README.md b/README.md index 77f8e4c..7122393 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,170 @@ -# Chemical-PFD +# Chemical PFD Tool ## +Repository for a Process Flow Diagram Software + + + + +[](https://wiki.c2.com/?CamelCase) +[](https://github.com/FOSSEE/Chemical-PFD/network/dependencies) +[](https://opensource.org/licenses/GPL-3.0) + +## Screenshots +> Main window +