now only correct chart can be created in SFC Viewer
authorSergey Surkov <surkovsv93@gmail.com>
Thu, 17 Nov 2016 14:04:44 +0300
changeset 1567 a4bf874e4949
parent 1566 2ce8d970fc69
child 1568 ad7c7df6cbeb
now only correct chart can be created in SFC Viewer

if user trying to connect incompatible blocks (by IEC 61131-3 standard), wire highlight will become red
editors/SFCViewer.py
editors/Viewer.py
--- a/editors/SFCViewer.py	Thu Nov 17 13:48:36 2016 +0300
+++ b/editors/SFCViewer.py	Thu Nov 17 14:04:44 2016 +0300
@@ -27,6 +27,56 @@
 import wx
 
 from Viewer import *
+from graphics.SFC_Objects import *
+from graphics.GraphicCommons import SELECTION_DIVERGENCE, \
+    SELECTION_CONVERGENCE, SIMULTANEOUS_DIVERGENCE, SIMULTANEOUS_CONVERGENCE, EAST, NORTH, WEST, SOUTH
+
+type = [SELECTION_DIVERGENCE, SELECTION_CONVERGENCE, SIMULTANEOUS_DIVERGENCE, SIMULTANEOUS_CONVERGENCE]
+divergence = dict(zip(type,["SELECTION_DIVERGENCE", "SELECTION_CONVERGENCE",\
+                            "SIMULTANEOUS_DIVERGENCE", "SIMULTANEOUS_CONVERGENCE"]))
+SFC_Objects = (SFC_Step, SFC_ActionBlock, SFC_Transition, SFC_Divergence, SFC_Jump)
+
+StandardRules = {
+    # The key of this dict is a block that user try to connect,
+    # and the value is a list of blocks, that can be connected with the current block.
+    "SFC_Step" :                 ["SFC_ActionBlock",
+                                  "SFC_Transition",
+                                  "SELECTION_DIVERGENCE",
+                                  "SIMULTANEOUS_CONVERGENCE"],
+
+    "SFC_ActionBlock" :          ["SFC_Step"],
+
+    "SFC_Transition" :           ["SFC_Step",
+                                  "SELECTION_CONVERGENCE",
+                                  "SIMULTANEOUS_DIVERGENCE",
+                                  "SFC_Jump",
+                                  "FBD_Block",
+                                  "FBD_Variable"
+                                  "LD_Contact",
+                                  "LD_PowerRail",
+                                  "LD_Coil"],
+
+    "SELECTION_DIVERGENCE" :     ["SFC_Transition"],
+
+    "SELECTION_CONVERGENCE" :    ["SFC_Step",
+                                  "SFC_Jump"],
+
+    "SIMULTANEOUS_DIVERGENCE" :  ["SFC_Step"],
+
+    "SIMULTANEOUS_CONVERGENCE" : ["SFC_Transition"],
+
+    "SFC_Jump" :                 [],
+
+    "FBD_Block" :                ["SFC_Transition"],
+
+    "FBD_Variable" :             ["SFC_Transition"],
+
+    "LD_Contact" :               ["SFC_Transition"],
+
+    "LD_PowerRail" :             ["SFC_Transition"],
+
+    "LD_Coil" :                  ["SFC_Transition"]
+                }
 
 class SFC_Viewer(Viewer):
     
@@ -282,6 +332,25 @@
             self.UpdateScrollPos(event)
         event.Skip()
 
+    def GetBlockName(self, block):
+        blockName = block.__class__.__name__
+        if blockName == "SFC_Divergence":
+            blockName = divergence[block.Type]
+        return blockName
+
+    # This method check the IEC 61131-3 compatibility between two SFC blocks
+    def BlockCompatibility(self,startblock = None, endblock = None, direction = None):
+        if startblock!= None and endblock != None and (isinstance(startblock,SFC_Objects)\
+                                                               or isinstance(endblock,SFC_Objects)):
+            # Full "StandardRules" table would be simmetrical and
+            # to avoid duplicate records and minimize the table only upper part is defined.
+            if (direction == SOUTH or direction == EAST):
+                startblock, endblock = endblock, startblock
+            start = self.GetBlockName(startblock)
+            end = self.GetBlockName(endblock)
+            return end in StandardRules[start]
+        return True
+
 #-------------------------------------------------------------------------------
 #                          Keyboard event functions
 #-------------------------------------------------------------------------------
--- a/editors/Viewer.py	Thu Nov 17 13:48:36 2016 +0300
+++ b/editors/Viewer.py	Thu Nov 17 14:04:44 2016 +0300
@@ -1467,12 +1467,16 @@
 
     def FindBlockConnectorWithError(self, pos, direction = None, exclude = None):
         error = False        
+        startblock = None
         for block in self.Blocks.itervalues():
             connector = block.TestConnector(pos, direction, exclude)
             if connector:
+                if self.IsWire(self.SelectedElement):
+                    startblock = self.SelectedElement.StartConnected.GetParentBlock()
                 avail, error = connector.ConnectionAvailable(direction, exclude)
-                if not avail:
+                if not avail or not self.BlockCompatibility(startblock, block, direction):
                     connector = None
+                    error = True
                 return connector, error
         return None, error
     
@@ -2349,6 +2353,9 @@
                 self.Scroll(xstart + move_window.x, ystart + move_window.y)
                 self.RefreshScrollBars(move_window.x, move_window.y)
 
+    def BlockCompatibility(self, startblock=None, endblock=None, direction = None):
+        return True
+
 #-------------------------------------------------------------------------------
 #                          Keyboard event functions
 #-------------------------------------------------------------------------------