summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBlaine2020-04-26 22:05:13 +0530
committerBlaine2020-04-26 22:05:13 +0530
commite3cdc7d698a3f400f600e13fa9e647a1d909aff2 (patch)
treeae5c756280cdfede808b64cc48bc221adabefcfe /src
parent0477ce548a303c20c33eb7abc8fe6166f18c3359 (diff)
downloadChemical-PFD-e3cdc7d698a3f400f600e13fa9e647a1d909aff2.tar.gz
Chemical-PFD-e3cdc7d698a3f400f600e13fa9e647a1d909aff2.tar.bz2
Chemical-PFD-e3cdc7d698a3f400f600e13fa9e647a1d909aff2.zip
comments and minor cleanup
Diffstat (limited to 'src')
-rw-r--r--src/main/python/main.py36
-rw-r--r--src/main/python/utils/canvas.py114
-rw-r--r--src/main/python/utils/dialogs.py32
-rw-r--r--src/main/python/utils/tabs.py26
4 files changed, 133 insertions, 75 deletions
diff --git a/src/main/python/main.py b/src/main/python/main.py
index 953c6c8..5afb350 100644
--- a/src/main/python/main.py
+++ b/src/main/python/main.py
@@ -15,39 +15,46 @@ from utils import dialogs
class appWindow(QMainWindow):
+ """
+ Application entry point, subclasses QMainWindow and implements the main widget,
+ sets necessary window behaviour etc.
+ """
def __init__(self, parent=None):
super(appWindow, self).__init__(parent)
+ self.mainWidget = QWidget(self) #create new widget
- titleMenu = self.menuBar()
- self.mainWidget = QWidget(self)
+ #create the menu bar
+ titleMenu = self.menuBar() #fetch reference to current menu bar
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)
+
self.menuGenerate = titleMenu.addMenu('Generate') #Generate menu
self.menuGenerate.addAction("Image", self.saveImage)
self.menuGenerate.addAction("Report", self.generateReport)
- # mainLayout = QGridLayout(self.mainWidget)
+ # create new layout for the main widget
mainLayout = QHBoxLayout(self.mainWidget)
mainLayout.setObjectName("Main Layout")
- #ImpsaveProject
- self.mdi = QMdiArea(self)
- # add close action to tabs
+ self.mdi = QMdiArea(self) #create area for files to be displayed
+ #create toolbar and add the toolbar plus mdi to layout
self.createToolbar()
mainLayout.addWidget(self.toolbar)
mainLayout.addWidget(self.mdi)
+
#declare main window layout
self.mainWidget.setLayout(mainLayout)
self.setCentralWidget(self.mainWidget)
- self.resize(1280, 720)
- self.setWindowState(Qt.WindowMaximized)
+ self.resize(1280, 720) #set collapse dim
+ self.setWindowState(Qt.WindowMaximized) #launch maximized
def createToolbar(self):
+ #place holder for toolbar with fixed width, layout may change
self.toolbar = QWidget(self.mainWidget)
self.toolbar.setObjectName("Toolbar")
self.toolbar.setFixedWidth(200)
@@ -55,15 +62,17 @@ class appWindow(QMainWindow):
self.toolbar.setLayout(toolbarLayout)
def newProject(self):
+ #call to create a new file inside mdi area
project = fileWindow(self.mdi)
project.setObjectName("New Project")
self.mdi.addSubWindow(project)
- if not project.tabList:
- project.newDiagram()
+ if not project.tabList: # important when unpickling a file instead
+ project.newDiagram() #create a new tab in the new file
project.show()
project.resizeHandler(self.mdi)
def openProject(self):
+ #show the open file dialog to open a saved file, then unpickle it.
name = QFileDialog.getOpenFileNames(self, 'Open File(s)', '', 'Process Flow Diagram (*pfd)')
if name:
for files in name[0]:
@@ -74,7 +83,8 @@ class appWindow(QMainWindow):
project.resizeHandler(self.mdi)
def saveProject(self):
- for j, i in enumerate(self.mdi.subWindowList()):
+ #pickle all files in mdi area
+ for j, i in enumerate(self.mdi.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)')
i.saveProject(name)
@@ -83,17 +93,21 @@ class appWindow(QMainWindow):
return True
def saveImage(self):
+ #place holder for future implementaion
pass
def generateReport(self):
+ #place holder for future implementaion
pass
def resizeEvent(self, event):
+ #overload resize to also handle resize on file windows inside
if self.mdi.activeSubWindow():
self.mdi.activeSubWindow().resizeHandler(self.mdi)
super(appWindow, self).resizeEvent(event)
def closeEvent(self, event):
+ #save alert on window close
if len(self.activeFiles) and dialogs.saveEvent(self):
event.accept()
else:
diff --git a/src/main/python/utils/canvas.py b/src/main/python/utils/canvas.py
index 330d3be..dac1d98 100644
--- a/src/main/python/utils/canvas.py
+++ b/src/main/python/utils/canvas.py
@@ -12,32 +12,48 @@ from .sizes import paperSizes, ppiList, sheetDimensionList
from .tabs import customTabWidget
class canvas(QWidget):
+ """
+ Defines the work area for a single sheet. Contains a QGraphicScene along with necessary properties
+ for context menu and dialogs.
+ """
+
def __init__(self, parent=None, size= 'A4', ppi= '72'):
super(canvas, self).__init__(parent)
+ #Store values for the canvas dimensions for ease of access, these are here just to be
+ # manipulated by the setters and getters
self._ppi = ppi
self._canvasSize = size
+ #Create area for the graphic items to be placed, this is just here right now for the future
+ # when we will draw items on this, this might be changed if QGraphicScene is subclassed.
self.painter = QGraphicsScene()
self.painter.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi])
- self.painter.setBackgroundBrush(QBrush(Qt.white))
+ self.painter.setBackgroundBrush(QBrush(Qt.white)) #set white background
- self.view = QGraphicsView(self.painter)
- self.view.setMinimumSize(595, 842)
- self.view.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi])
+ self.view = QGraphicsView(self.painter) #create a viewport for the canvas board
+ self.view.setMinimumSize(595, 842) #experimentation for the viewport overflow
+ self.view.setSceneRect(0, 0, *paperSizes[self.canvasSize][self.ppi]) # use the dimensions set previously
- self.layout = QHBoxLayout(self)
+ self.layout = QHBoxLayout(self) #create the layout of the canvas, the canvas could just subclass QGView instead
self.layout.addWidget(self.view)
self.setLayout(self.layout)
+ #This is done so that a right click menu is shown on right click
self.setContextMenuPolicy(Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.contextMenu)
def setCanvasSize(self, size):
+ """
+ extended setter for dialog box
+ """
self.canvasSize = size
- def setCanvasPPI(self, ppi):
+ def setCanvasPPI(self, ppi):
+ """
+ extended setter for dialog box
+ """
self.ppi = ppi
@property
@@ -63,16 +79,21 @@ class canvas(QWidget):
@property
def dimensions(self):
+ #returns the dimension of the current scene
return self.painter.sceneRect().width(), self.painter.sceneRect().height()
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
self.canvasSize, self.ppi = dialogs.paperDims(self, self._canvasSize, self._ppi, self.objectName).exec_()
+ #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__,
@@ -93,54 +114,43 @@ class canvas(QWidget):
self.painter.addItem(graphic)
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)
- self.tabber.tabCloseRequested.connect(self.closeTab)
- self.tabber.currentChanged.connect(self.changeTab)
- self.tabber.plusClicked.connect(self.newDiagram)
+ 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
+ #assign layout to widget
self.setWidget(self.tabber)
- self.setWindowTitle(title)
-
- @property
- def canvasSize(self):
- return self._canvasSize
- @property
- def ppi(self):
- return self._ppi
-
- @canvasSize.setter
- def canvasSize(self, size):
- self._canvasSize = sheetDimensionList.index(size)
- if self.tabCount:
- activeTab = self.tabber.currentWidget()
- activeTab.canvasSize = size
-
- @ppi.setter
- def ppi(self, ppi):
- self._ppi = ppiList.index(ppi)
- if self.tabCount:
- activeTab = self.tabber.currentWidget()
- activeTab.ppi = ppi
-
+ self.setWindowTitle(title)
def changeTab(self, currentIndex):
+ #placeholder function to detect tab change
pass
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.rect() if parent else self.parent().rect()
self.resize(parentRect.width(), parentRect.height())
self.setMaximumHeight(parentRect.height())
@@ -150,12 +160,34 @@ class fileWindow(QMdiSubWindow):
@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__,
@@ -172,18 +204,4 @@ class fileWindow(QMdiSubWindow):
diagram.__setstate__(i)
self.tabber.addTab(diagram, i['ObjectName'])
- def saveProject(self, name = None):
- 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):
- if self.tabCount==0 or dialogs.saveEvent(self):
- event.accept()
- self.deleteLater()
- else:
- event.ignore()
+ \ No newline at end of file
diff --git a/src/main/python/utils/dialogs.py b/src/main/python/utils/dialogs.py
index d2b872c..38d68d9 100644
--- a/src/main/python/utils/dialogs.py
+++ b/src/main/python/utils/dialogs.py
@@ -2,52 +2,66 @@ from PyQt5.QtWidgets import QDialog, QPushButton, QFormLayout, QComboBox, QLabel
from .sizes import sheetDimensionList, ppiList
class paperDims(QDialog):
+ """
+ Utility dialog box to adjust the current canvas's dimensions, might return just dimensions later
+ so that sizes do not need to be imported in every other module.
+ """
def __init__(self, parent=None, size='A4', ppi='72', name='Canvas Size'):
super(paperDims, self).__init__(parent)
+ #store initial values to show currently set value, also updated when changed. these are returned at EOL
self._canvasSize = size
self._ppi = ppi
- self.setWindowTitle(name+":Canvas Size")
+ self.setWindowTitle(name+":Canvas Size") #Set Window Title
+ #init layout
dialogBoxLayout = QFormLayout(self)
- sizeComboBox = QComboBox()
+
+ sizeComboBox = QComboBox() #combo box for paper sizes
sizeComboBox.addItems(sheetDimensionList)
sizeComboBox.setCurrentIndex(4)
sizeComboBox.activated[str].connect(self.setCanvasSize)
sizeLabel = QLabel("Canvas Size")
- sizeLabel.setBuddy(sizeComboBox)
- sizeComboBox.setCurrentIndex(sheetDimensionList.index(self._canvasSize))
+ sizeLabel.setBuddy(sizeComboBox) # label for the above combo box
+ sizeComboBox.setCurrentIndex(sheetDimensionList.index(self._canvasSize)) #set index to current value of canvas
dialogBoxLayout.setWidget(0, QFormLayout.LabelRole, sizeLabel)
dialogBoxLayout.setWidget(0, QFormLayout.FieldRole, sizeComboBox)
- ppiComboBox = QComboBox()
+ ppiComboBox = QComboBox() #combo box for ppis
ppiComboBox.addItems(ppiList)
ppiComboBox.activated[str].connect(self.setCanvasPPI)
ppiLabel = QLabel("Canvas ppi")
- ppiLabel.setBuddy(ppiComboBox)
- ppiComboBox.setCurrentIndex(ppiList.index(self._ppi))
+ ppiLabel.setBuddy(ppiComboBox) # label for the above combo box
+ ppiComboBox.setCurrentIndex(ppiList.index(self._ppi)) #set index to current value of canvas
dialogBoxLayout.setWidget(1, QFormLayout.LabelRole, ppiLabel)
dialogBoxLayout.setWidget(1, QFormLayout.FieldRole, ppiComboBox)
self.setLayout(dialogBoxLayout)
- self.resize(400,300)
+ self.resize(400,300) #resize to a certain size
+
+ #todo add ok or cancel buttons
def setCanvasSize(self, size):
+ #for standard combo box behaviour
self._canvasSize = size
def setCanvasPPI(self, ppi):
+ #for standard combo box behaviour
self._ppi = ppi
def exec_(self):
+ #overload exec_ to add return values and delete itself(currently being tested)
super(paperDims, self).exec_()
+ self.deleteLater()
return self._canvasSize, self._ppi
def saveEvent(parent = None):
+ #utility function to generate a Qt alert window requesting the user to save the file, returns user intention on window close
alert = QMessageBox.question(parent, parent.objectName(), "All unsaved progress will be LOST!",
QMessageBox.StandardButtons(QMessageBox.Save|QMessageBox.Ignore|QMessageBox.Cancel), QMessageBox.Save)
if alert == QMessageBox.Cancel:
return False
else:
if alert == QMessageBox.Save:
- if not parent.saveProject():
+ if not parent.saveProject(): #the parent's saveProject method is called which returns false if saving was cancelled by the user
return False
return True \ No newline at end of file
diff --git a/src/main/python/utils/tabs.py b/src/main/python/utils/tabs.py
index 3dfb641..7d8bb1d 100644
--- a/src/main/python/utils/tabs.py
+++ b/src/main/python/utils/tabs.py
@@ -2,6 +2,9 @@ from PyQt5.QtWidgets import QTabBar, QPushButton, QTabWidget
from PyQt5.QtCore import pyqtSignal, QSize
class tabBarPlus(QTabBar):
+ """
+ Just implemented to overload resize and layout change to emit a signal
+ """
layoutChanged = pyqtSignal()
def resizeEvent(self, event):
super().resizeEvent(event)
@@ -13,26 +16,35 @@ class tabBarPlus(QTabBar):
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
+ """
plusClicked = pyqtSignal()
def __init__(self, parent=None):
super(customTabWidget, self).__init__(parent)
self.tab = tabBarPlus()
- self.setTabBar(self.tab)
+ self.setTabBar(self.tab) #set tabBar to our custom tabBarPlus
- self.plusButton = QPushButton('+', self)
- self.plusButton.setFixedSize(35, 25)
- self.plusButton.clicked.connect(self.plusClicked.emit)
+ self.plusButton = QPushButton('+', self) #create the new tab button
+ #and parent it to the widget to add it at 0, 0
+ self.plusButton.setFixedSize(35, 25) #set dimensions
+ self.plusButton.clicked.connect(self.plusClicked.emit) #emit signal on click
+ #set flags
self.setMovable(True)
self.setTabsClosable(True)
- self.tab.layoutChanged.connect(self.movePlusButton)
+ self.tab.layoutChanged.connect(self.movePlusButton) #connect layout change
+ # to dynamically move the button.
def movePlusButton(self):
+ #move the new tab button to correct location
size = sum([self.tab.tabRect(i).width() for i in range(self.tab.count())])
- h = max(self.tab.geometry().bottom() - 25, 0)
+ # calculate width of all tabs
+ h = max(self.tab.geometry().bottom() - 25, 0) #align with bottom of tabbar
w = self.tab.width()
- if size > w:
+ if size > w: #if all the tabs do not overflow the tab bar, add at the end
self.plusButton.move(w-self.plusButton.width(), h)
else:
self.plusButton.move(size-3, h) \ No newline at end of file