--- a/Dialogs.py Tue Aug 12 16:28:55 2008 +0200
+++ b/Dialogs.py Tue Aug 12 16:30:39 2008 +0200
@@ -162,6 +162,8 @@
self.Preview.SetBackgroundColour(wx.Colour(255,255,255))
setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
setattr(self.Preview, "GetScaling", lambda:None)
+ setattr(self.Preview, "GetBlockType", self.Controler.GetBlockType)
+ setattr(self.Preview, "IsOfType", self.Controler.IsOfType)
self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
if wx.VERSION >= (2, 5, 0):
@@ -173,7 +175,8 @@
self._init_sizers()
- def __init__(self, parent):
+ def __init__(self, parent, controler):
+ self.Controler = controler
self._init_ctrls(parent)
self.BlockName.SetValue("")
self.BlockName.Enable(False)
@@ -299,7 +302,7 @@
selected = event.GetItem()
pydata = self.TypeTree.GetPyData(selected)
if pydata["type"] != CATEGORY:
- blocktype = GetBlockType(self.TypeTree.GetItemText(selected), pydata["inputs"])
+ blocktype = self.Controler.GetBlockType(self.TypeTree.GetItemText(selected), pydata["inputs"])
if blocktype:
self.Inputs.SetValue(len(blocktype["inputs"]))
self.Inputs.Enable(blocktype["extensible"])
@@ -451,7 +454,7 @@
self.SetSizer(self.flexGridSizer1)
- def _init_ctrls(self, prnt):
+ def _init_ctrls(self, prnt, ctrler):
wx.Dialog.__init__(self, id=ID_VARIABLEPROPERTIESDIALOG,
name='VariablePropertiesDialog', parent=prnt, pos=wx.Point(376, 223),
size=wx.Size(400, 380), style=wx.DEFAULT_DIALOG_STYLE,
@@ -508,6 +511,7 @@
self.Preview.SetBackgroundColour(wx.Colour(255,255,255))
setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
setattr(self.Preview, "GetScaling", lambda:None)
+ setattr(self.Preview, "IsOfType", ctrler.IsOfType)
self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
@@ -518,8 +522,8 @@
self._init_sizers()
- def __init__(self, parent):
- self._init_ctrls(parent)
+ def __init__(self, parent, controler):
+ self._init_ctrls(parent, controler)
self.Variable = None
self.VarList = []
self.MinVariableSize = None
@@ -733,7 +737,7 @@
self.SetSizer(self.flexGridSizer1)
- def _init_ctrls(self, prnt):
+ def _init_ctrls(self, prnt, ctrler):
wx.Dialog.__init__(self, id=ID_CONNECTIONPROPERTIESDIALOG,
name='ConnectionPropertiesDialog', parent=prnt, pos=wx.Point(376, 223),
size=wx.Size(350, 220), style=wx.DEFAULT_DIALOG_STYLE,
@@ -775,6 +779,7 @@
self.Preview.SetBackgroundColour(wx.Colour(255,255,255))
setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
setattr(self.Preview, "GetScaling", lambda:None)
+ setattr(self.Preview, "IsOfType", ctrler.IsOfType)
self.Spacer = wx.Panel(id=ID_CONNECTIONPROPERTIESDIALOGSPACER,
name='Spacer', parent=self, pos=wx.Point(0, 0),
@@ -789,8 +794,8 @@
self._init_sizers()
- def __init__(self, parent):
- self._init_ctrls(parent)
+ def __init__(self, parent, controler):
+ self._init_ctrls(parent, controler)
self.Connection = None
self.MinConnectionSize = None
@@ -923,7 +928,7 @@
self.SetSizer(self.flexGridSizer1)
- def _init_ctrls(self, prnt, title, labels):
+ def _init_ctrls(self, prnt, ctrler, title, labels):
wx.Dialog.__init__(self, id=ID_LDELEMENTDIALOG,
name='LDElementDialog', parent=prnt, pos=wx.Point(376, 223),
size=wx.Size(350, 260), style=wx.DEFAULT_DIALOG_STYLE,
@@ -974,6 +979,7 @@
self.Preview.SetBackgroundColour(wx.Colour(255,255,255))
setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
setattr(self.Preview, "GetScaling", lambda:None)
+ setattr(self.Preview, "IsOfType", ctrler.IsOfType)
self.Spacer = wx.Panel(id=ID_LDELEMENTDIALOGSPACER,
name='Spacer', parent=self, pos=wx.Point(0, 0),
@@ -988,13 +994,13 @@
self._init_sizers()
- def __init__(self, parent, type):
+ def __init__(self, parent, controler, type):
self.Type = type
if type == "contact":
- self._init_ctrls(parent, "Edit Contact Values", ['Normal','Negate','Rising Edge','Falling Edge'])
+ self._init_ctrls(parent, controler, "Edit Contact Values", ['Normal','Negate','Rising Edge','Falling Edge'])
self.Element = LD_Contact(self.Preview, CONTACT_NORMAL, "")
elif type == "coil":
- self._init_ctrls(parent, "Edit Coil Values", ['Normal','Negate','Set','Reset'])
+ self._init_ctrls(parent, controler, "Edit Coil Values", ['Normal','Negate','Set','Reset'])
self.Element = LD_Coil(self.Preview, COIL_NORMAL, "")
def SetPreviewFont(self, font):
@@ -1154,7 +1160,7 @@
self.SetSizer(self.flexGridSizer1)
- def _init_ctrls(self, prnt):
+ def _init_ctrls(self, prnt, ctrler):
wx.Dialog.__init__(self, id=ID_LDPOWERRAILDIALOG,
name='PowerRailDialog', parent=prnt, pos=wx.Point(376, 223),
size=wx.Size(350, 260), style=wx.DEFAULT_DIALOG_STYLE,
@@ -1195,6 +1201,7 @@
self.Preview.SetBackgroundColour(wx.Colour(255,255,255))
setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
setattr(self.Preview, "GetScaling", lambda:None)
+ setattr(self.Preview, "IsOfType", ctrler.IsOfType)
self.Spacer = wx.Panel(id=ID_LDELEMENTDIALOGSPACER,
name='Spacer', parent=self, pos=wx.Point(0, 0),
@@ -1209,8 +1216,8 @@
self._init_sizers()
- def __init__(self, parent, type = LEFTRAIL, number = 1):
- self._init_ctrls(parent)
+ def __init__(self, parent, controler, type = LEFTRAIL, number = 1):
+ self._init_ctrls(parent, controler)
self.Type = type
if type == LEFTRAIL:
self.radioButton1.SetValue(True)
@@ -1333,7 +1340,7 @@
self.SetSizer(self.flexGridSizer1)
- def _init_ctrls(self, prnt):
+ def _init_ctrls(self, prnt, ctrler):
wx.Dialog.__init__(self, id=ID_STEPCONTENTDIALOG,
name='StepContentDialog', parent=prnt, pos=wx.Point(376, 223),
size=wx.Size(400, 250), style=wx.DEFAULT_DIALOG_STYLE,
@@ -1383,6 +1390,7 @@
setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
setattr(self.Preview, "RefreshStepModel", lambda x:None)
setattr(self.Preview, "GetScaling", lambda:None)
+ setattr(self.Preview, "IsOfType", ctrler.IsOfType)
self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
if wx.VERSION >= (2, 5, 0):
@@ -1394,8 +1402,8 @@
self._init_sizers()
- def __init__(self, parent, initial = False):
- self._init_ctrls(parent)
+ def __init__(self, parent, controler, initial = False):
+ self._init_ctrls(parent, controler)
self.Step = None
self.Initial = initial
self.MinStepSize = None
@@ -1579,7 +1587,7 @@
self.SetSizer(self.flexGridSizer1)
- def _init_ctrls(self, prnt):
+ def _init_ctrls(self, prnt, ctrler):
wx.Dialog.__init__(self, id=ID_TRANSITIONCONTENTDIALOG,
name='ProjectDialog', parent=prnt, pos=wx.Point(376, 223),
size=wx.Size(350, 300), style=wx.DEFAULT_DIALOG_STYLE,
@@ -1641,6 +1649,7 @@
setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
setattr(self.Preview, "RefreshTransitionModel", lambda x:None)
setattr(self.Preview, "GetScaling", lambda:None)
+ setattr(self.Preview, "IsOfType", ctrler.IsOfType)
self.Spacer = wx.Panel(id=ID_TRANSITIONCONTENTDIALOGSPACER,
name='Spacer', parent=self, pos=wx.Point(0, 0),
@@ -1656,9 +1665,9 @@
self._init_sizers()
- def __init__(self, parent, connection):
+ def __init__(self, parent, controler, connection):
self.Connection = connection
- self._init_ctrls(parent)
+ self._init_ctrls(parent, controler)
self.Transition = None
self.MinTransitionSize = None
@@ -1856,7 +1865,7 @@
self.SetSizer(self.flexGridSizer1)
- def _init_ctrls(self, prnt):
+ def _init_ctrls(self, prnt, ctrler):
wx.Dialog.__init__(self, id=ID_DIVERGENCECREATEDIALOG,
name='DivergencePropertiesDialog', parent=prnt, pos=wx.Point(376, 223),
size=wx.Size(500, 300), style=wx.DEFAULT_DIALOG_STYLE,
@@ -1909,6 +1918,7 @@
size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
self.Preview.SetBackgroundColour(wx.Colour(255,255,255))
setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
+ setattr(self.Preview, "IsOfType", ctrler.IsOfType)
self.Spacer = wx.Panel(id=ID_TRANSITIONCONTENTDIALOGSPACER,
name='Spacer', parent=self, pos=wx.Point(0, 0),
@@ -1923,8 +1933,8 @@
self._init_sizers()
- def __init__(self, parent):
- self._init_ctrls(parent)
+ def __init__(self, parent, controler):
+ self._init_ctrls(parent, controler)
self.Divergence = None
self.MinSize = (0, 0)
--- a/PLCControler.py Tue Aug 12 16:28:55 2008 +0200
+++ b/PLCControler.py Tue Aug 12 16:30:39 2008 +0200
@@ -162,16 +162,13 @@
self.Buffering = False
self.FilePath = ""
self.FileName = ""
+ self.ProgramChunks = []
+ self.PluginTypes = []
self.ProgramFilePath = ""
- self.RefreshDataTypeUsingTree()
- self.RefreshDataTypes()
- self.RefreshPouUsingTree()
- self.RefreshBlockTypes()
-
+
def GetQualifierTypes(self):
return plcopen.QualifierList
-
#-------------------------------------------------------------------------------
# Project management functions
#-------------------------------------------------------------------------------
@@ -269,41 +266,54 @@
# Return project informations
def GetProjectInfos(self):
if self.Project:
- infos = {"name": self.Project.getname(), "type": ITEM_PROJECT}
- datatypes = {"name": "Data Types", "type": ITEM_DATATYPES, "values":[]}
+ infos = {"name": self.Project.getname(), "type": ITEM_PROJECT, "tagname": ""}
+ datatypes = {"name": "Data Types", "type": ITEM_DATATYPES, "tagname": "", "values":[]}
for datatype in self.Project.getdataTypes():
- datatypes["values"].append({"name": datatype.getname(), "type": ITEM_DATATYPE, "values": []})
- pou_types = {"function": {"name": "Functions", "type": ITEM_FUNCTION, "values":[]},
- "functionBlock": {"name": "Function Blocks", "type": ITEM_FUNCTIONBLOCK, "values":[]},
- "program": {"name": "Programs", "type": ITEM_PROGRAM, "values":[]}}
+ datatypes["values"].append({"name": datatype.getname(), "type": ITEM_DATATYPE,
+ "tagname": self.ComputeDataTypeName(datatype.getname()), "values": []})
+ pou_types = {"function": {"name": "Functions", "type": ITEM_FUNCTION, "tagname": "", "values":[]},
+ "functionBlock": {"name": "Function Blocks", "type": ITEM_FUNCTIONBLOCK, "tagname": "", "values":[]},
+ "program": {"name": "Programs", "type": ITEM_PROGRAM, "tagname": "", "values":[]}}
for pou in self.Project.getpous():
pou_type = pou.getpouType()
- pou_infos = {"name": pou.getname(), "type": ITEM_POU}
+ pou_infos = {"name": pou.getname(), "type": ITEM_POU,
+ "tagname": self.ComputePouName(pou.getname())}
pou_values = []
if pou.getbodyType() == "SFC":
transitions = []
for transition in pou.gettransitionList():
- transitions.append({"name": transition.getname(), "type": ITEM_TRANSITION, "values": []})
- pou_values.append({"name": "Transitions", "type": ITEM_TRANSITIONS, "values": transitions})
+ transitions.append({"name": transition.getname(), "type": ITEM_TRANSITION,
+ "tagname": self.ComputePouTransitionName(pou.getname(), transition.getname()),
+ "values": []})
+ pou_values.append({"name": "Transitions", "type": ITEM_TRANSITIONS,
+ "tagname": "", "values": transitions})
actions = []
for action in pou.getactionList():
- actions.append({"name": action.getname(), "type": ITEM_ACTION, "values": []})
- pou_values.append({"name": "Actions", "type": ITEM_ACTIONS, "values": actions})
+ actions.append({"name": action.getname(), "type": ITEM_ACTION,
+ "tagname": self.ComputePouActionName(pou.getname(), action.getname()),
+ "values": []})
+ pou_values.append({"name": "Actions", "type": ITEM_ACTIONS,
+ "tagname": "", "values": actions})
if pou_type in pou_types:
pou_infos["values"] = pou_values
pou_types[pou_type]["values"].append(pou_infos)
- configurations = {"name": "Configurations", "type": ITEM_CONFIGURATIONS, "values": []}
+ configurations = {"name": "Configurations", "type": ITEM_CONFIGURATIONS,
+ "tagname": "", "values": []}
for config in self.Project.getconfigurations():
config_name = config.getname()
- config_infos = {"name": config_name, "type": ITEM_CONFIGURATION, "values": []}
- resources = {"name": "Resources", "type": ITEM_RESOURCES, "values": []}
+ config_infos = {"name": config_name, "type": ITEM_CONFIGURATION,
+ "tagname": self.ComputeConfigurationName(config.getname()),
+ "values": []}
+ resources = {"name": "Resources", "type": ITEM_RESOURCES, "tagname": "", "values": []}
for resource in config.getresource():
resource_name = resource.getname()
- resource_infos = {"name": resource_name, "type": ITEM_RESOURCE, "values": []}
+ resource_infos = {"name": resource_name, "type": ITEM_RESOURCE,
+ "tagname": self.ComputeConfigurationResourceName(config.getname(), resource.getname()),
+ "values": []}
resources["values"].append(resource_infos)
config_infos["values"] = [resources]
configurations["values"].append(config_infos)
- infos["values"] = [{"name": "Properties", "type": ITEM_PROPERTIES, "values": []},
+ infos["values"] = [{"name": "Properties", "type": ITEM_PROPERTIES, "tagname": "", "values": []},
datatypes, pou_types["function"], pou_types["functionBlock"],
pou_types["program"], configurations]
return infos
@@ -379,7 +389,7 @@
pou_infos["values"].append({"name" : "%s(%s)"%(variable.getname(), vartype_content["name"]),
"type" : ITEM_VARIABLE, "values" : []})
return pou_infos
- block_infos = GetBlockType(type)
+ block_infos = self.GetBlockType(type)
if block_infos is not None and block_infos["type"] != "function":
pou_infos = {"name" : "%s(%s)"%(name, type), "type" : ITEM_POU, "values" : []}
for varname, vartype, varmodifier in block_infos["inputs"]:
@@ -392,126 +402,26 @@
return {"name" : "%s(%s)"%(name, type), "type" : ITEM_VARIABLE, "values" : []}
return None
-
- # Refresh the tree of user-defined data type cross-use
- def RefreshDataTypeUsingTree(self):
- # Reset the tree of user-defined pou cross-use
- self.DataTypeUsingTree = {}
- if self.Project:
- datatypes = self.Project.getdataTypes()
- # Reference all the user-defined data type names and initialize the tree of
- # user-defined data type cross-use
- datatypenames = [datatype.getname() for datatype in datatypes]
- for name in datatypenames:
- self.DataTypeUsingTree[name] = []
- # Analyze each data type
- for datatype in datatypes:
- name = datatype.getname()
- basetype_content = datatype.getbaseType().getcontent()
- if basetype_content["name"] == "derived":
- basetype_name = basetype_content["value"].getname()
- if basetype_name in datatypenames and name not in self.DataTypeUsingTree[basetype_name]:
- self.DataTypeUsingTree[basetype_name].append(name)
- elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned", "array"]:
- base_type = basetype_content["value"].baseType.getcontent()
- if base_type["value"] is not None:
- basetype_name = base_type["value"].getname()
- if basetype_name in datatypenames and name not in self.DataTypeUsingTree[basetype_name]:
- self.DataTypeUsingTree[basetype_name].append(name)
-
- # Refresh the tree of user-defined pou cross-use
- def RefreshPouUsingTree(self):
- # Reset the tree of user-defined pou cross-use
- self.PouUsingTree = {}
- if self.Project:
- pous = self.Project.getpous()
- # Reference all the user-defined pou names and initialize the tree of
- # user-defined pou cross-use
- pounames = [pou.getname() for pou in pous]
- for name in pounames:
- self.PouUsingTree[name] = []
- # Analyze each pou
- for pou in pous:
- name = pou.getname()
- if pou.interface:
- # Extract variables from every varLists
- for type, varlist in pou.getvars():
- for var in varlist.getvariable():
- vartype_content = var.gettype().getcontent()
- if vartype_content["name"] == "derived":
- typename = vartype_content["value"].getname()
- if typename in pounames and name not in self.PouUsingTree[typename]:
- self.PouUsingTree[typename].append(name)
- bodytype = pou.getbodyType()
- # If pou is written in a graphical language
- if bodytype in ["FBD","LD","SFC"]:
- # Analyze each instance of the pou
- for instance in pou.getinstances():
- if isinstance(instance, plcopen.fbdObjects_block):
- typename = instance.gettypeName()
- # Update tree if there is a cross-use
- if typename in pounames and name not in self.PouUsingTree[typename]:
- self.PouUsingTree[typename].append(name)
- # If pou is written in a textual language
- elif bodytype in ["IL", "ST"]:
- text = pou.gettext()
- # Search if each pou is mentioned in the pou text
- for typename in pounames:
- typename_model = re.compile("[ \t\n]%s[ \t\n]"%typename)
- # Update tree if there is a cross-use
- if typename != name and typename_model.search(text):
- self.PouUsingTree[typename].append(name)
# Return if data type given by name is used by another data type or pou
def DataTypeIsUsed(self, name):
- if name in self.DataTypeUsingTree:
- return len(self.DataTypeUsingTree[name]) > 0
- return False
+ return self.Project.ElementIsUsed(name) or self.Project.DataTypeIsDerived(name)
# Return if pou given by name is used by another pou
def PouIsUsed(self, name):
- if name in self.PouUsingTree:
- return len(self.PouUsingTree[name]) > 0
- return False
-
- # Return if data type given by name is directly or undirectly used by the reference data type
- def DataTypeIsUsedBy(self, name, reference):
- if name in self.DataTypeUsingTree:
- list = self.DataTypeUsingTree[name]
- # Test if data type is directly used by reference
- if reference in list:
- return True
- else:
- # Test if data type is undirectly used by reference, by testing if data types
- # that directly use data type is directly or undirectly used by reference
- used = False
- for element in list:
- used |= self.DataTypeIsUsedBy(element, reference)
- return used
- return False
+ return self.Project.ElementIsUsed(name)
# Return if pou given by name is directly or undirectly used by the reference pou
def PouIsUsedBy(self, name, reference):
- if name in self.PouUsingTree:
- list = self.PouUsingTree[name]
- # Test if pou is directly used by reference
- if reference in list:
- return True
- else:
- # Test if pou is undirectly used by reference, by testing if pous
- # that directly use pou is directly or undirectly used by reference
- used = False
- for element in list:
- used |= self.PouIsUsedBy(element, reference)
- return used
- return False
+ return self.Project.ElementIsUsedBy(name, reference)
def GenerateProgram(self, filepath):
if self.Project:
try:
- program = GenerateCurrentProgram(self.Project)
+ self.ProgramChunks = GenerateCurrentProgram(self, self.Project)
+ program_text = "".join([item[0] for item in self.ProgramChunks])
programfile = open(filepath, "w")
- programfile.write(program)
+ programfile.write(program_text)
programfile.close()
self.ProgramFilePath = filepath
return None
@@ -519,6 +429,23 @@
return e.message
return "No project opened"
+ def GetChunkInfos(self, from_location, to_location):
+ row = col = 1
+ infos = []
+ for chunk, chunk_infos in self.ProgramChunks:
+ lines = chunk.split("\n")
+ if len(lines) > 1:
+ next_row = row + len(lines) - 1
+ next_col = len(lines[-1]) + 1
+ else:
+ next_col = col + len(chunk)
+ if next_row >= from_location[0] and next_col >= from_location[1] and len(chunk_infos) > 0:
+ infos.append((chunk_infos, (row, col)))
+ if next_row == to_location[0] and next_col > to_location[1] or next_row > to_location[0]:
+ return infos
+ row, col = next_row, next_col
+ return infos
+
#-------------------------------------------------------------------------------
# Project Pous management functions
#-------------------------------------------------------------------------------
@@ -527,15 +454,11 @@
def ProjectAddDataType(self, datatype_name):
# Add the pou to project
self.Project.appenddataType(datatype_name)
- self.RefreshDataTypeUsingTree()
- self.RefreshDataTypes()
self.BufferProject()
# Remove a Data Type from project
def ProjectRemoveDataType(self, datatype_name):
self.Project.removedataType(datatype_name)
- self.RefreshDataTypeUsingTree()
- self.RefreshDataTypes()
self.BufferProject()
# Add a Pou to Project
@@ -544,15 +467,11 @@
self.Project.appendpou(pou_name, pou_type, body_type)
if pou_type == "function":
self.SetPouInterfaceReturnType(pou_name, "BOOL")
- self.RefreshPouUsingTree()
- self.RefreshBlockTypes()
self.BufferProject()
# Remove a Pou from project
def ProjectRemovePou(self, pou_name):
self.Project.removepou(pou_name)
- self.RefreshPouUsingTree()
- self.RefreshBlockTypes()
self.BufferProject()
# Add a configuration to Project
@@ -618,8 +537,8 @@
pou = self.Project.getpou(old_name)
pou.setname(new_name)
self.Project.updateElementName(old_name, new_name)
- self.RefreshPouUsingTree()
- self.RefreshBlockTypes()
+ self.Project.RefreshElementUsingTree()
+ self.Project.RefreshCustomBlockTypes()
self.BufferProject()
# Change the name of a pou transition
@@ -648,7 +567,7 @@
for var in varlist.getvariable():
if var.getname() == old_name:
var.setname(new_name)
- self.RefreshBlockTypes()
+ self.Project.RefreshCustomBlockTypes()
self.BufferProject()
# Change the name of a configuration
@@ -784,7 +703,6 @@
configuration.setglobalVars([])
for vartype, varlist in self.ExtractVarLists(vars):
configuration.globalVars.append(varlist)
- self.RefreshBlockTypes()
# Return the configuration globalvars
def GetConfigurationGlobalVars(self, name):
@@ -834,7 +752,6 @@
resource.setglobalVars([])
for vartype, varlist in self.ExtractVarLists(vars):
resource.globalVars.append(varlist)
- self.RefreshBlockTypes()
# Return the resource globalvars
def GetConfigurationResourceGlobalVars(self, config_name, name):
@@ -928,8 +845,8 @@
pou.interface = plcopen.pou_interface()
# Set Pou interface
pou.setvars(self.ExtractVarLists(vars))
- self.RefreshPouUsingTree()
- self.RefreshBlockTypes()
+ self.Project.RefreshElementUsingTree()
+ self.Project.RefreshCustomBlockTypes()
# Replace the return type of the pou given by its name (only for functions)
def SetPouInterfaceReturnType(self, name, type):
@@ -953,7 +870,8 @@
derived_type = plcopen.derivedTypes_derived()
derived_type.setname(type)
return_type.setcontent({"name" : "derived", "value" : derived_type})
- self.RefreshBlockTypes()
+ self.Project.RefreshElementUsingTree()
+ self.Project.RefreshCustomBlockTypes()
def UpdateProjectUsedPous(self, old_name, new_name):
if self.Project:
@@ -984,108 +902,43 @@
else:
return returntype_content["name"]
return None
-
- # Update data types with user-defined data types added
- def RefreshDataTypes(self):
- ResetTypeHierarchy()
- ResetEnumeratedDataValues()
+
+ # Function that add a new plugin to the plugin list
+ def AddPluginBlockList(self, blocklist):
+ self.PluginTypes.extend(blocklist)
+
+ # Function that clear the plugin list
+ def ClearPluginTypes(self):
+ for i in xrange(len(self.PluginTypes)):
+ self.PluginTypes.pop(0)
+
+ # Function that returns the block definition associated to the block type given
+ def GetBlockType(self, type, inputs = None):
+ for category in BlockTypes + self.PluginTypes:
+ for blocktype in category["list"]:
+ if inputs:
+ block_inputs = tuple([var_type for name, var_type, modifier in blocktype["inputs"]])
+ same_inputs = inputs == block_inputs
+ else:
+ same_inputs = True
+ if blocktype["name"] == type and same_inputs:
+ return blocktype
if self.Project:
- for datatype in self.Project.getdataTypes():
- name = datatype.getname()
- basetype_content = datatype.getbaseType().getcontent()
- if basetype_content["value"] is None:
- AddDataTypeHierarchy(name, basetype_content["name"])
- elif basetype_content["name"] in ["string", "wstring"]:
- AddDataTypeHierarchy(name, basetype_content["name"].upper())
- elif basetype_content["name"] == "derived":
- AddDataTypeHierarchy(name, basetype_content["value"].getname())
- elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned"]:
- base_type = basetype_content["value"].baseType.getcontent()
- if base_type["value"] is None:
- AddDataTypeHierarchy(name, base_type["name"])
- else:
- AddDataTypeHierarchy(name, base_type["value"].getname())
- else:
- if basetype_content["name"] == "enum":
- values = []
- for value in basetype_content["value"].values.getvalue():
- values.append(value.getname())
- AddEnumeratedDataValues(values)
- AddDataTypeHierarchy(name, "ANY_DERIVED")
-
- # Update Block types with user-defined pou added
- def RefreshBlockTypes(self):
- if BlockTypes[-1]["name"] == "User-defined POUs":
- BlockTypes[-1]["list"] = []
- else:
- BlockTypes.append({"name" : "User-defined POUs", "list": []})
- if self.Project:
- for pou in self.Project.getpous():
- pou_name = pou.getname()
- pou_type = pou.getpouType()
- if pou_type != "program":
- block_infos = {"name" : pou_name, "type" : pou_type, "extensible" : False,
- "inputs" : [], "outputs" : [], "comment" : "",
- "generate" : generate_block, "initialise" : initialise_block }
- if pou.getinterface():
- for type, varlist in pou.getvars():
- if type == "InOut":
- for var in varlist.getvariable():
- var_type = var.type.getcontent()
- if var_type["name"] == "derived":
- block_infos["inputs"].append((var.getname(), var_type["value"].getname(), "none"))
- block_infos["outputs"].append((var.getname(), var_type["value"].getname(), "none"))
- elif var_type["name"] in ["string", "wstring"]:
- block_infos["inputs"].append((var.getname(), var_type["name"].upper(), "none"))
- block_infos["outputs"].append((var.getname(), var_type["name"].upper(), "none"))
- else:
- block_infos["inputs"].append((var.getname(), var_type["name"], "none"))
- block_infos["outputs"].append((var.getname(), var_type["name"], "none"))
- elif type == "Input":
- for var in varlist.getvariable():
- var_type = var.type.getcontent()
- if var_type["name"] == "derived":
- block_infos["inputs"].append((var.getname(), var_type["value"].getname(), "none"))
- elif var_type["name"] in ["string", "wstring"]:
- block_infos["inputs"].append((var.getname(), var_type["name"].upper(), "none"))
- else:
- block_infos["inputs"].append((var.getname(), var_type["name"], "none"))
- elif type == "Output":
- for var in varlist.getvariable():
- var_type = var.type.getcontent()
- if var_type["name"] == "derived":
- block_infos["outputs"].append((var.getname(), var_type["value"].getname(), "none"))
- elif var_type["name"] in ["string", "wstring"]:
- block_infos["outputs"].append((var.getname(), var_type["name"].upper(), "none"))
- else:
- block_infos["outputs"].append((var.getname(), var_type["name"], "none"))
- return_type = pou.interface.getreturnType()
- if return_type:
- var_type = return_type.getcontent()
- if var_type["name"] == "derived":
- block_infos["outputs"].append(("", var_type["value"].getname(), "none"))
- elif var_type["name"] in ["string", "wstring"]:
- block_infos["outputs"].append(("", var_type["name"].upper(), "none"))
- else:
- block_infos["outputs"].append(("", var_type["name"], "none"))
- if pou.getbodyType() in ["FBD","LD","SFC"]:
- for instance in pou.getinstances():
- if isinstance(instance, plcopen.commonObjects_comment):
- block_infos["comment"] = instance.getcontentText()
- BlockTypes[-1]["list"].append(block_infos)
-
+ return self.Project.GetCustomBlockType(type, inputs)
+ return None
+
# Return Block types checking for recursion
def GetBlockTypes(self, tagname = ""):
- name = ""
type = None
if self.Project:
+ name = ""
words = tagname.split("::")
if words[0] in ["P","T","A"]:
name = words[1]
type = self.GetPouType(name)
if type == "function":
blocktypes = []
- for category in BlockTypes[:-1] + PluginTypes:
+ for category in BlockTypes + self.PluginTypes:
cat = {"name" : category["name"], "list" : []}
for block in category["list"]:
if block["type"] == "function":
@@ -1093,32 +946,24 @@
if len(cat["list"]) > 0:
blocktypes.append(cat)
else:
- blocktypes = [category for category in BlockTypes[:-1] + PluginTypes]
+ blocktypes = [category for category in BlockTypes + self.PluginTypes]
if self.Project:
- blocktypes.append({"name" : "User-defined POUs", "list": []})
- for blocktype in BlockTypes[-1]["list"]:
- if blocktype["name"] != name and not self.PouIsUsedBy(name, blocktype["name"]) and not (type == "function" and blocktype["type"] != "function"):
- blocktypes[-1]["list"].append(blocktype)
+ blocktypes.append({"name" : "User-defined POUs", "list": self.Project.GetCustomBlockTypes(name)})
return blocktypes
# Return Function Block types checking for recursion
def GetFunctionBlockTypes(self, tagname = ""):
- name = ""
- type = None
- if self.Project:
- words = tagname.split("::")
- if words[0] in ["P","T","A"]:
- name = words[1]
- type = self.GetPouType(name)
blocktypes = []
- for category in BlockTypes[:-1]:
+ for category in BlockTypes + self.PluginTypes:
for block in category["list"]:
if block["type"] != "function":
blocktypes.append(block["name"])
if self.Project:
- for blocktype in BlockTypes[-1]["list"]:
- if blocktype["name"] != name and not self.PouIsUsedBy(name, blocktype["name"]) and not (type == "function" and blocktype["type"] != "function"):
- blocktypes.append(blocktype["name"])
+ name = ""
+ words = tagname.split("::")
+ if words[0] in ["P","T","A"]:
+ name = words[1]
+ blocktypes.extend(self.Project.GetCustomFunctionBlockTypes(name))
return blocktypes
# Return Block types checking for recursion
@@ -1129,9 +974,7 @@
if blocktype["type"] == "program":
blocktypes.append(blocktype["name"])
if self.Project:
- for pou in self.Project.getpous():
- if pou.getpouType() == "program":
- blocktypes.append(pou.getname())
+ blocktypes.extend(self.Project.GetCustomBlockResource())
return blocktypes
# Return Data Types checking for recursion
@@ -1141,32 +984,58 @@
else:
datatypes = []
if self.Project:
+ name = ""
words = tagname.split("::")
if words[0] in ["D"]:
name = words[1]
- else:
- name = ""
- for datatype in self.Project.getdataTypes():
- datatype_name = datatype.getname()
- if datatype_name != name and not self.DataTypeIsUsedBy(name, datatype_name):
- datatypes.append(datatype_name)
+ datatypes.extend(self.Project.GetCustomDataTypes(name))
return datatypes
# Return Base Type of given possible derived type
def GetBaseType(self, type):
- return GetBaseType(type)
+ if self.Project:
+ return self.Project.GetBaseType(type)
+ return None
# Return Base Types
def GetBaseTypes(self):
- return [value for value, parent in TypeHierarchy_list if not value.startswith("ANY")]
-
+ return [value for value in TypeHierarchy.keys() if not value.startswith("ANY")]
+
+ def IsOfType(self, type, reference):
+ if self.Project:
+ return self.Project.IsOfType(type, reference)
+ elif reference is None:
+ return True
+ elif type == reference:
+ return True
+ else:
+ if type in TypeHierarchy:
+ return self.IsOfType(TypeHierarchy[type], reference)
+ return None
+
+ def IsEndType(self, type):
+ if type is not None:
+ return not type.startswith("ANY")
+ return True
+
+ def GetDataTypeRange(self, type):
+ if self.Project:
+ return self.Project.GetDataTypeRange(type)
+ elif type in DataTypeRange:
+ return DataTypeRange[type]
+ return None
+
# Return Subrange types
- def GetSubrangeTypes(self):
- return [value for value, range in DataTypeRange_list]
-
+ def GetSubrangeBaseTypes(self, exclude):
+ if self.Project:
+ return self.Project.GetSubrangeBaseTypes(exclude)
+ return []
+
# Return Enumerated Values
def GetEnumeratedDataValues(self):
- return EnumeratedDataValues
+ if self.Project:
+ return self.Project.GetEnumeratedDataTypeValues()
+ return []
#-------------------------------------------------------------------------------
# Project Element tag name computation functions
@@ -1196,6 +1065,12 @@
def ComputeConfigurationResourceName(self, config, resource):
return "R::%s::%s" % (config, resource)
+ def GetElementType(self, tagname):
+ words = tagname.split("::")
+ return {"D" : ITEM_DATATYPE, "P" : ITEM_POU,
+ "T" : ITEM_TRANSITION, "A" : ITEM_ACTION,
+ "C" : ITEM_CONFIGURATION, "R" : ITEM_RESOURCE}[words[0]]
+
#-------------------------------------------------------------------------------
# Project opened Data types management functions
#-------------------------------------------------------------------------------
@@ -1314,8 +1189,7 @@
datatype.initialValue.setvalue(infos["initial"])
else:
datatype.initialValue = None
- self.RefreshDataTypeUsingTree()
- self.RefreshDataTypes()
+ self.Project.RefreshDataTypeHierarchy()
self.BufferProject()
#-------------------------------------------------------------------------------
@@ -1325,9 +1199,11 @@
# Return edited element
def GetEditedElement(self, tagname):
words = tagname.split("::")
- if words[0] == "P":
+ if words[0] == "D":
+ return self.Project.getdataType(words[1])
+ elif words[0] == "P":
return self.Project.getpou(words[1])
- if words[0] in ['T', 'A']:
+ elif words[0] in ['T', 'A']:
pou = self.Project.getpou(words[1])
if words[0] == 'T':
return pou.gettransition(words[2])
@@ -1342,7 +1218,7 @@
# Return edited element name
def GetEditedElementName(self, tagname):
words = tagname.split("::")
- if words[0] in ["P","C"]:
+ if words[0] in ["P","C","D"]:
return words[1]
else:
return words[2]
@@ -1790,7 +1666,7 @@
block = plcopen.fbdObjects_block()
block.setlocalId(id)
block.settypeName(blocktype)
- blocktype_infos = GetBlockType(blocktype)
+ blocktype_infos = self.GetBlockType(blocktype)
if blocktype_infos["type"] != "function" and blockname is not None:
block.setinstanceName(blockname)
self.AddEditedElementPouVar(tagname, blocktype, blockname)
@@ -1807,8 +1683,8 @@
old_type = block.gettypeName()
new_name = infos.get("name", old_name)
new_type = infos.get("type", old_type)
- old_typeinfos = GetBlockType(old_type)
- new_typeinfos = GetBlockType(new_type)
+ old_typeinfos = self.GetBlockType(old_type)
+ new_typeinfos = self.GetBlockType(new_type)
if new_typeinfos["type"] != old_typeinfos["type"]:
if new_typeinfos["type"] == "function":
self.RemoveEditedElementPouVar(tagname, old_type, old_name)
@@ -2463,14 +2339,13 @@
if child.nodeType == tree.ELEMENT_NODE and child.nodeName == "project":
self.Project.loadXMLTree(child, ["xmlns", "xmlns:xhtml", "xmlns:xsi", "xsi:schemaLocation"])
self.SetFilePath(filepath)
+ self.Project.RefreshElementUsingTree()
+ self.Project.RefreshDataTypeHierarchy()
+ self.Project.RefreshCustomBlockTypes()
self.ProjectBuffer = UndoBuffer(self.Copy(self.Project), True)
self.Buffering = False
self.ElementsOpened = []
self.CurrentElementEditing = None
- self.RefreshDataTypeUsingTree()
- self.RefreshDataTypes()
- self.RefreshPouUsingTree()
- self.RefreshBlockTypes()
return None
return "No PLC project found"