1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
import pickle
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QMdiSubWindow, QFileDialog, QMenu
from . import dialogs
from .canvas import canvas
from .tabs import customTabWidget
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.
"""
def __init__(self, parent = None, title = 'New Project', size = 'A4', ppi = '72'):
super(fileWindow, self).__init__(parent)
#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.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
self.tabber.plusClicked.connect(self.newDiagram) #connect the new tab button to add a new tab
# self.tabber.setContentsMargins(0, 1, 1, 1)
#assign layout to widget
self.setWidget(self.tabber)
self.setWindowTitle(title)
#This is done so that a right click menu is shown on right click
self.setContextMenuPolicy(Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.contextMenu)
def changeTab(self, currentIndex):
#placeholder function to detect tab change
self.resizeHandler()
def closeTab(self, currentIndex):
#show save alert on tab close
if dialogs.saveEvent(self):
self.tabber.widget(currentIndex).deleteLater()
self.tabber.removeTab(currentIndex)
def newDiagram(self):
# helper function to add a new tab on pressing new tab button, using the add tab method on QTabWidget
diagram = canvas(self.tabber)
diagram.setObjectName("New")
self.tabber.addTab(diagram, "New")
def resizeHandler(self, parent = None):
# experimental resize Handler to handle resize on parent resize.
parentRect = parent.parentWidget().rect() if parent else self.parentWidget().parentWidget().rect()
current = self.tabber.currentWidget()
width, height = current.dimensions
width = min(parentRect.width(), width + 100)
height = min(parentRect.height(), height + 200)
self.setFixedSize(width, height)
self.tabber.resize(width, height)
self.tabber.currentWidget().adjustView()
def contextMenu(self, point):
#function to display the right click menu at point of right click
menu = QMenu("Context Menu", self)
menu.addAction("Adjust Canvas", self.adjustCanvasDialog)
menu.exec_(self.mapToGlobal(point))
def adjustCanvasDialog(self):
#helper function to the context menu dialog box
currentTab = self.tabber.currentWidget()
currentTab.canvasSize, currentTab.ppi = dialogs.paperDims(self, currentTab._canvasSize, currentTab._ppi, currentTab.objectName()).exec_()
self.resizeHandler()
def resizeEvent(self, event):
self.resizeHandler()
super(fileWindow, self).resizeEvent(event)
@property
def tabList(self):
#returns a list of tabs in the given window
return [self.tabber.widget(i) for i in range(self.tabCount)]
@property
def tabCount(self):
#returns the number of tabs in the given window only
return self.tabber.count()
def saveProject(self, name = None):
# called by dialog.saveEvent, saves the current file
name = QFileDialog.getSaveFileName(self, 'Save File', f'New Diagram', 'Process Flow Diagram (*.pfd)') if not name else name
if name:
with open(name[0],'wb') as file:
pickle.dump(self, file)
return True
else:
return False
def closeEvent(self, event):
# handle save alert on file close, check if current file has no tabs aswell.
if self.tabCount==0 or dialogs.saveEvent(self):
event.accept()
self.deleteLater()
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.
def __getstate__(self) -> dict:
return {
"_classname_": self.__class__.__name__,
"ObjectName": self.objectName(),
"ppi": self._ppi,
"canvasSize": self._canvasSize,
"tabs": [i.__getstate__() for i in self.tabList]
}
def __setstate__(self, dict):
self.__init__(title = dict['ObjectName'])
for i in dict['tabs']:
diagram = canvas(self.tabber, size = dict['canvasSize'], ppi = dict['ppi'])
diagram.__setstate__(i)
self.tabber.addTab(diagram, i['ObjectName'])
|