267 return properties |
264 return properties |
268 |
265 |
269 # Return project informations |
266 # Return project informations |
270 def GetProjectInfos(self): |
267 def GetProjectInfos(self): |
271 if self.Project: |
268 if self.Project: |
272 infos = {"name": self.Project.getname(), "type": ITEM_PROJECT} |
269 infos = {"name": self.Project.getname(), "type": ITEM_PROJECT, "tagname": ""} |
273 datatypes = {"name": "Data Types", "type": ITEM_DATATYPES, "values":[]} |
270 datatypes = {"name": "Data Types", "type": ITEM_DATATYPES, "tagname": "", "values":[]} |
274 for datatype in self.Project.getdataTypes(): |
271 for datatype in self.Project.getdataTypes(): |
275 datatypes["values"].append({"name": datatype.getname(), "type": ITEM_DATATYPE, "values": []}) |
272 datatypes["values"].append({"name": datatype.getname(), "type": ITEM_DATATYPE, |
276 pou_types = {"function": {"name": "Functions", "type": ITEM_FUNCTION, "values":[]}, |
273 "tagname": self.ComputeDataTypeName(datatype.getname()), "values": []}) |
277 "functionBlock": {"name": "Function Blocks", "type": ITEM_FUNCTIONBLOCK, "values":[]}, |
274 pou_types = {"function": {"name": "Functions", "type": ITEM_FUNCTION, "tagname": "", "values":[]}, |
278 "program": {"name": "Programs", "type": ITEM_PROGRAM, "values":[]}} |
275 "functionBlock": {"name": "Function Blocks", "type": ITEM_FUNCTIONBLOCK, "tagname": "", "values":[]}, |
|
276 "program": {"name": "Programs", "type": ITEM_PROGRAM, "tagname": "", "values":[]}} |
279 for pou in self.Project.getpous(): |
277 for pou in self.Project.getpous(): |
280 pou_type = pou.getpouType() |
278 pou_type = pou.getpouType() |
281 pou_infos = {"name": pou.getname(), "type": ITEM_POU} |
279 pou_infos = {"name": pou.getname(), "type": ITEM_POU, |
|
280 "tagname": self.ComputePouName(pou.getname())} |
282 pou_values = [] |
281 pou_values = [] |
283 if pou.getbodyType() == "SFC": |
282 if pou.getbodyType() == "SFC": |
284 transitions = [] |
283 transitions = [] |
285 for transition in pou.gettransitionList(): |
284 for transition in pou.gettransitionList(): |
286 transitions.append({"name": transition.getname(), "type": ITEM_TRANSITION, "values": []}) |
285 transitions.append({"name": transition.getname(), "type": ITEM_TRANSITION, |
287 pou_values.append({"name": "Transitions", "type": ITEM_TRANSITIONS, "values": transitions}) |
286 "tagname": self.ComputePouTransitionName(pou.getname(), transition.getname()), |
|
287 "values": []}) |
|
288 pou_values.append({"name": "Transitions", "type": ITEM_TRANSITIONS, |
|
289 "tagname": "", "values": transitions}) |
288 actions = [] |
290 actions = [] |
289 for action in pou.getactionList(): |
291 for action in pou.getactionList(): |
290 actions.append({"name": action.getname(), "type": ITEM_ACTION, "values": []}) |
292 actions.append({"name": action.getname(), "type": ITEM_ACTION, |
291 pou_values.append({"name": "Actions", "type": ITEM_ACTIONS, "values": actions}) |
293 "tagname": self.ComputePouActionName(pou.getname(), action.getname()), |
|
294 "values": []}) |
|
295 pou_values.append({"name": "Actions", "type": ITEM_ACTIONS, |
|
296 "tagname": "", "values": actions}) |
292 if pou_type in pou_types: |
297 if pou_type in pou_types: |
293 pou_infos["values"] = pou_values |
298 pou_infos["values"] = pou_values |
294 pou_types[pou_type]["values"].append(pou_infos) |
299 pou_types[pou_type]["values"].append(pou_infos) |
295 configurations = {"name": "Configurations", "type": ITEM_CONFIGURATIONS, "values": []} |
300 configurations = {"name": "Configurations", "type": ITEM_CONFIGURATIONS, |
|
301 "tagname": "", "values": []} |
296 for config in self.Project.getconfigurations(): |
302 for config in self.Project.getconfigurations(): |
297 config_name = config.getname() |
303 config_name = config.getname() |
298 config_infos = {"name": config_name, "type": ITEM_CONFIGURATION, "values": []} |
304 config_infos = {"name": config_name, "type": ITEM_CONFIGURATION, |
299 resources = {"name": "Resources", "type": ITEM_RESOURCES, "values": []} |
305 "tagname": self.ComputeConfigurationName(config.getname()), |
|
306 "values": []} |
|
307 resources = {"name": "Resources", "type": ITEM_RESOURCES, "tagname": "", "values": []} |
300 for resource in config.getresource(): |
308 for resource in config.getresource(): |
301 resource_name = resource.getname() |
309 resource_name = resource.getname() |
302 resource_infos = {"name": resource_name, "type": ITEM_RESOURCE, "values": []} |
310 resource_infos = {"name": resource_name, "type": ITEM_RESOURCE, |
|
311 "tagname": self.ComputeConfigurationResourceName(config.getname(), resource.getname()), |
|
312 "values": []} |
303 resources["values"].append(resource_infos) |
313 resources["values"].append(resource_infos) |
304 config_infos["values"] = [resources] |
314 config_infos["values"] = [resources] |
305 configurations["values"].append(config_infos) |
315 configurations["values"].append(config_infos) |
306 infos["values"] = [{"name": "Properties", "type": ITEM_PROPERTIES, "values": []}, |
316 infos["values"] = [{"name": "Properties", "type": ITEM_PROPERTIES, "tagname": "", "values": []}, |
307 datatypes, pou_types["function"], pou_types["functionBlock"], |
317 datatypes, pou_types["function"], pou_types["functionBlock"], |
308 pou_types["program"], configurations] |
318 pou_types["program"], configurations] |
309 return infos |
319 return infos |
310 return None |
320 return None |
311 |
321 |
390 |
400 |
391 if type in TypeHierarchy: |
401 if type in TypeHierarchy: |
392 return {"name" : "%s(%s)"%(name, type), "type" : ITEM_VARIABLE, "values" : []} |
402 return {"name" : "%s(%s)"%(name, type), "type" : ITEM_VARIABLE, "values" : []} |
393 |
403 |
394 return None |
404 return None |
395 |
|
396 # Refresh the tree of user-defined data type cross-use |
|
397 def RefreshDataTypeUsingTree(self): |
|
398 # Reset the tree of user-defined pou cross-use |
|
399 self.DataTypeUsingTree = {} |
|
400 if self.Project: |
|
401 datatypes = self.Project.getdataTypes() |
|
402 # Reference all the user-defined data type names and initialize the tree of |
|
403 # user-defined data type cross-use |
|
404 datatypenames = [datatype.getname() for datatype in datatypes] |
|
405 for name in datatypenames: |
|
406 self.DataTypeUsingTree[name] = [] |
|
407 # Analyze each data type |
|
408 for datatype in datatypes: |
|
409 name = datatype.getname() |
|
410 basetype_content = datatype.getbaseType().getcontent() |
|
411 if basetype_content["name"] == "derived": |
|
412 basetype_name = basetype_content["value"].getname() |
|
413 if basetype_name in datatypenames and name not in self.DataTypeUsingTree[basetype_name]: |
|
414 self.DataTypeUsingTree[basetype_name].append(name) |
|
415 elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned", "array"]: |
|
416 base_type = basetype_content["value"].baseType.getcontent() |
|
417 if base_type["value"] is not None: |
|
418 basetype_name = base_type["value"].getname() |
|
419 if basetype_name in datatypenames and name not in self.DataTypeUsingTree[basetype_name]: |
|
420 self.DataTypeUsingTree[basetype_name].append(name) |
|
421 |
|
422 # Refresh the tree of user-defined pou cross-use |
|
423 def RefreshPouUsingTree(self): |
|
424 # Reset the tree of user-defined pou cross-use |
|
425 self.PouUsingTree = {} |
|
426 if self.Project: |
|
427 pous = self.Project.getpous() |
|
428 # Reference all the user-defined pou names and initialize the tree of |
|
429 # user-defined pou cross-use |
|
430 pounames = [pou.getname() for pou in pous] |
|
431 for name in pounames: |
|
432 self.PouUsingTree[name] = [] |
|
433 # Analyze each pou |
|
434 for pou in pous: |
|
435 name = pou.getname() |
|
436 if pou.interface: |
|
437 # Extract variables from every varLists |
|
438 for type, varlist in pou.getvars(): |
|
439 for var in varlist.getvariable(): |
|
440 vartype_content = var.gettype().getcontent() |
|
441 if vartype_content["name"] == "derived": |
|
442 typename = vartype_content["value"].getname() |
|
443 if typename in pounames and name not in self.PouUsingTree[typename]: |
|
444 self.PouUsingTree[typename].append(name) |
|
445 bodytype = pou.getbodyType() |
|
446 # If pou is written in a graphical language |
|
447 if bodytype in ["FBD","LD","SFC"]: |
|
448 # Analyze each instance of the pou |
|
449 for instance in pou.getinstances(): |
|
450 if isinstance(instance, plcopen.fbdObjects_block): |
|
451 typename = instance.gettypeName() |
|
452 # Update tree if there is a cross-use |
|
453 if typename in pounames and name not in self.PouUsingTree[typename]: |
|
454 self.PouUsingTree[typename].append(name) |
|
455 # If pou is written in a textual language |
|
456 elif bodytype in ["IL", "ST"]: |
|
457 text = pou.gettext() |
|
458 # Search if each pou is mentioned in the pou text |
|
459 for typename in pounames: |
|
460 typename_model = re.compile("[ \t\n]%s[ \t\n]"%typename) |
|
461 # Update tree if there is a cross-use |
|
462 if typename != name and typename_model.search(text): |
|
463 self.PouUsingTree[typename].append(name) |
|
464 |
405 |
465 # Return if data type given by name is used by another data type or pou |
406 # Return if data type given by name is used by another data type or pou |
466 def DataTypeIsUsed(self, name): |
407 def DataTypeIsUsed(self, name): |
467 if name in self.DataTypeUsingTree: |
408 return self.Project.ElementIsUsed(name) or self.Project.DataTypeIsDerived(name) |
468 return len(self.DataTypeUsingTree[name]) > 0 |
|
469 return False |
|
470 |
409 |
471 # Return if pou given by name is used by another pou |
410 # Return if pou given by name is used by another pou |
472 def PouIsUsed(self, name): |
411 def PouIsUsed(self, name): |
473 if name in self.PouUsingTree: |
412 return self.Project.ElementIsUsed(name) |
474 return len(self.PouUsingTree[name]) > 0 |
|
475 return False |
|
476 |
|
477 # Return if data type given by name is directly or undirectly used by the reference data type |
|
478 def DataTypeIsUsedBy(self, name, reference): |
|
479 if name in self.DataTypeUsingTree: |
|
480 list = self.DataTypeUsingTree[name] |
|
481 # Test if data type is directly used by reference |
|
482 if reference in list: |
|
483 return True |
|
484 else: |
|
485 # Test if data type is undirectly used by reference, by testing if data types |
|
486 # that directly use data type is directly or undirectly used by reference |
|
487 used = False |
|
488 for element in list: |
|
489 used |= self.DataTypeIsUsedBy(element, reference) |
|
490 return used |
|
491 return False |
|
492 |
413 |
493 # Return if pou given by name is directly or undirectly used by the reference pou |
414 # Return if pou given by name is directly or undirectly used by the reference pou |
494 def PouIsUsedBy(self, name, reference): |
415 def PouIsUsedBy(self, name, reference): |
495 if name in self.PouUsingTree: |
416 return self.Project.ElementIsUsedBy(name, reference) |
496 list = self.PouUsingTree[name] |
|
497 # Test if pou is directly used by reference |
|
498 if reference in list: |
|
499 return True |
|
500 else: |
|
501 # Test if pou is undirectly used by reference, by testing if pous |
|
502 # that directly use pou is directly or undirectly used by reference |
|
503 used = False |
|
504 for element in list: |
|
505 used |= self.PouIsUsedBy(element, reference) |
|
506 return used |
|
507 return False |
|
508 |
417 |
509 def GenerateProgram(self, filepath): |
418 def GenerateProgram(self, filepath): |
510 if self.Project: |
419 if self.Project: |
511 try: |
420 try: |
512 program = GenerateCurrentProgram(self.Project) |
421 self.ProgramChunks = GenerateCurrentProgram(self, self.Project) |
|
422 program_text = "".join([item[0] for item in self.ProgramChunks]) |
513 programfile = open(filepath, "w") |
423 programfile = open(filepath, "w") |
514 programfile.write(program) |
424 programfile.write(program_text) |
515 programfile.close() |
425 programfile.close() |
516 self.ProgramFilePath = filepath |
426 self.ProgramFilePath = filepath |
517 return None |
427 return None |
518 except PLCGenException, e: |
428 except PLCGenException, e: |
519 return e.message |
429 return e.message |
520 return "No project opened" |
430 return "No project opened" |
521 |
431 |
|
432 def GetChunkInfos(self, from_location, to_location): |
|
433 row = col = 1 |
|
434 infos = [] |
|
435 for chunk, chunk_infos in self.ProgramChunks: |
|
436 lines = chunk.split("\n") |
|
437 if len(lines) > 1: |
|
438 next_row = row + len(lines) - 1 |
|
439 next_col = len(lines[-1]) + 1 |
|
440 else: |
|
441 next_col = col + len(chunk) |
|
442 if next_row >= from_location[0] and next_col >= from_location[1] and len(chunk_infos) > 0: |
|
443 infos.append((chunk_infos, (row, col))) |
|
444 if next_row == to_location[0] and next_col > to_location[1] or next_row > to_location[0]: |
|
445 return infos |
|
446 row, col = next_row, next_col |
|
447 return infos |
|
448 |
522 #------------------------------------------------------------------------------- |
449 #------------------------------------------------------------------------------- |
523 # Project Pous management functions |
450 # Project Pous management functions |
524 #------------------------------------------------------------------------------- |
451 #------------------------------------------------------------------------------- |
525 |
452 |
526 # Add a Data Type to Project |
453 # Add a Data Type to Project |
527 def ProjectAddDataType(self, datatype_name): |
454 def ProjectAddDataType(self, datatype_name): |
528 # Add the pou to project |
455 # Add the pou to project |
529 self.Project.appenddataType(datatype_name) |
456 self.Project.appenddataType(datatype_name) |
530 self.RefreshDataTypeUsingTree() |
|
531 self.RefreshDataTypes() |
|
532 self.BufferProject() |
457 self.BufferProject() |
533 |
458 |
534 # Remove a Data Type from project |
459 # Remove a Data Type from project |
535 def ProjectRemoveDataType(self, datatype_name): |
460 def ProjectRemoveDataType(self, datatype_name): |
536 self.Project.removedataType(datatype_name) |
461 self.Project.removedataType(datatype_name) |
537 self.RefreshDataTypeUsingTree() |
|
538 self.RefreshDataTypes() |
|
539 self.BufferProject() |
462 self.BufferProject() |
540 |
463 |
541 # Add a Pou to Project |
464 # Add a Pou to Project |
542 def ProjectAddPou(self, pou_name, pou_type, body_type): |
465 def ProjectAddPou(self, pou_name, pou_type, body_type): |
543 # Add the pou to project |
466 # Add the pou to project |
544 self.Project.appendpou(pou_name, pou_type, body_type) |
467 self.Project.appendpou(pou_name, pou_type, body_type) |
545 if pou_type == "function": |
468 if pou_type == "function": |
546 self.SetPouInterfaceReturnType(pou_name, "BOOL") |
469 self.SetPouInterfaceReturnType(pou_name, "BOOL") |
547 self.RefreshPouUsingTree() |
|
548 self.RefreshBlockTypes() |
|
549 self.BufferProject() |
470 self.BufferProject() |
550 |
471 |
551 # Remove a Pou from project |
472 # Remove a Pou from project |
552 def ProjectRemovePou(self, pou_name): |
473 def ProjectRemovePou(self, pou_name): |
553 self.Project.removepou(pou_name) |
474 self.Project.removepou(pou_name) |
554 self.RefreshPouUsingTree() |
|
555 self.RefreshBlockTypes() |
|
556 self.BufferProject() |
475 self.BufferProject() |
557 |
476 |
558 # Add a configuration to Project |
477 # Add a configuration to Project |
559 def ProjectAddConfiguration(self, config_name): |
478 def ProjectAddConfiguration(self, config_name): |
560 self.Project.addconfiguration(config_name) |
479 self.Project.addconfiguration(config_name) |
982 elif returntype_content["name"] in ["string", "wstring"]: |
900 elif returntype_content["name"] in ["string", "wstring"]: |
983 return returntype_content["name"].upper() |
901 return returntype_content["name"].upper() |
984 else: |
902 else: |
985 return returntype_content["name"] |
903 return returntype_content["name"] |
986 return None |
904 return None |
987 |
905 |
988 # Update data types with user-defined data types added |
906 # Function that add a new plugin to the plugin list |
989 def RefreshDataTypes(self): |
907 def AddPluginBlockList(self, blocklist): |
990 ResetTypeHierarchy() |
908 self.PluginTypes.extend(blocklist) |
991 ResetEnumeratedDataValues() |
909 |
|
910 # Function that clear the plugin list |
|
911 def ClearPluginTypes(self): |
|
912 for i in xrange(len(self.PluginTypes)): |
|
913 self.PluginTypes.pop(0) |
|
914 |
|
915 # Function that returns the block definition associated to the block type given |
|
916 def GetBlockType(self, type, inputs = None): |
|
917 for category in BlockTypes + self.PluginTypes: |
|
918 for blocktype in category["list"]: |
|
919 if inputs: |
|
920 block_inputs = tuple([var_type for name, var_type, modifier in blocktype["inputs"]]) |
|
921 same_inputs = inputs == block_inputs |
|
922 else: |
|
923 same_inputs = True |
|
924 if blocktype["name"] == type and same_inputs: |
|
925 return blocktype |
992 if self.Project: |
926 if self.Project: |
993 for datatype in self.Project.getdataTypes(): |
927 return self.Project.GetCustomBlockType(type, inputs) |
994 name = datatype.getname() |
928 return None |
995 basetype_content = datatype.getbaseType().getcontent() |
929 |
996 if basetype_content["value"] is None: |
|
997 AddDataTypeHierarchy(name, basetype_content["name"]) |
|
998 elif basetype_content["name"] in ["string", "wstring"]: |
|
999 AddDataTypeHierarchy(name, basetype_content["name"].upper()) |
|
1000 elif basetype_content["name"] == "derived": |
|
1001 AddDataTypeHierarchy(name, basetype_content["value"].getname()) |
|
1002 elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned"]: |
|
1003 base_type = basetype_content["value"].baseType.getcontent() |
|
1004 if base_type["value"] is None: |
|
1005 AddDataTypeHierarchy(name, base_type["name"]) |
|
1006 else: |
|
1007 AddDataTypeHierarchy(name, base_type["value"].getname()) |
|
1008 else: |
|
1009 if basetype_content["name"] == "enum": |
|
1010 values = [] |
|
1011 for value in basetype_content["value"].values.getvalue(): |
|
1012 values.append(value.getname()) |
|
1013 AddEnumeratedDataValues(values) |
|
1014 AddDataTypeHierarchy(name, "ANY_DERIVED") |
|
1015 |
|
1016 # Update Block types with user-defined pou added |
|
1017 def RefreshBlockTypes(self): |
|
1018 if BlockTypes[-1]["name"] == "User-defined POUs": |
|
1019 BlockTypes[-1]["list"] = [] |
|
1020 else: |
|
1021 BlockTypes.append({"name" : "User-defined POUs", "list": []}) |
|
1022 if self.Project: |
|
1023 for pou in self.Project.getpous(): |
|
1024 pou_name = pou.getname() |
|
1025 pou_type = pou.getpouType() |
|
1026 if pou_type != "program": |
|
1027 block_infos = {"name" : pou_name, "type" : pou_type, "extensible" : False, |
|
1028 "inputs" : [], "outputs" : [], "comment" : "", |
|
1029 "generate" : generate_block, "initialise" : initialise_block } |
|
1030 if pou.getinterface(): |
|
1031 for type, varlist in pou.getvars(): |
|
1032 if type == "InOut": |
|
1033 for var in varlist.getvariable(): |
|
1034 var_type = var.type.getcontent() |
|
1035 if var_type["name"] == "derived": |
|
1036 block_infos["inputs"].append((var.getname(), var_type["value"].getname(), "none")) |
|
1037 block_infos["outputs"].append((var.getname(), var_type["value"].getname(), "none")) |
|
1038 elif var_type["name"] in ["string", "wstring"]: |
|
1039 block_infos["inputs"].append((var.getname(), var_type["name"].upper(), "none")) |
|
1040 block_infos["outputs"].append((var.getname(), var_type["name"].upper(), "none")) |
|
1041 else: |
|
1042 block_infos["inputs"].append((var.getname(), var_type["name"], "none")) |
|
1043 block_infos["outputs"].append((var.getname(), var_type["name"], "none")) |
|
1044 elif type == "Input": |
|
1045 for var in varlist.getvariable(): |
|
1046 var_type = var.type.getcontent() |
|
1047 if var_type["name"] == "derived": |
|
1048 block_infos["inputs"].append((var.getname(), var_type["value"].getname(), "none")) |
|
1049 elif var_type["name"] in ["string", "wstring"]: |
|
1050 block_infos["inputs"].append((var.getname(), var_type["name"].upper(), "none")) |
|
1051 else: |
|
1052 block_infos["inputs"].append((var.getname(), var_type["name"], "none")) |
|
1053 elif type == "Output": |
|
1054 for var in varlist.getvariable(): |
|
1055 var_type = var.type.getcontent() |
|
1056 if var_type["name"] == "derived": |
|
1057 block_infos["outputs"].append((var.getname(), var_type["value"].getname(), "none")) |
|
1058 elif var_type["name"] in ["string", "wstring"]: |
|
1059 block_infos["outputs"].append((var.getname(), var_type["name"].upper(), "none")) |
|
1060 else: |
|
1061 block_infos["outputs"].append((var.getname(), var_type["name"], "none")) |
|
1062 return_type = pou.interface.getreturnType() |
|
1063 if return_type: |
|
1064 var_type = return_type.getcontent() |
|
1065 if var_type["name"] == "derived": |
|
1066 block_infos["outputs"].append(("", var_type["value"].getname(), "none")) |
|
1067 elif var_type["name"] in ["string", "wstring"]: |
|
1068 block_infos["outputs"].append(("", var_type["name"].upper(), "none")) |
|
1069 else: |
|
1070 block_infos["outputs"].append(("", var_type["name"], "none")) |
|
1071 if pou.getbodyType() in ["FBD","LD","SFC"]: |
|
1072 for instance in pou.getinstances(): |
|
1073 if isinstance(instance, plcopen.commonObjects_comment): |
|
1074 block_infos["comment"] = instance.getcontentText() |
|
1075 BlockTypes[-1]["list"].append(block_infos) |
|
1076 |
|
1077 # Return Block types checking for recursion |
930 # Return Block types checking for recursion |
1078 def GetBlockTypes(self, tagname = ""): |
931 def GetBlockTypes(self, tagname = ""): |
1079 name = "" |
|
1080 type = None |
932 type = None |
1081 if self.Project: |
933 if self.Project: |
|
934 name = "" |
1082 words = tagname.split("::") |
935 words = tagname.split("::") |
1083 if words[0] in ["P","T","A"]: |
936 if words[0] in ["P","T","A"]: |
1084 name = words[1] |
937 name = words[1] |
1085 type = self.GetPouType(name) |
938 type = self.GetPouType(name) |
1086 if type == "function": |
939 if type == "function": |
1087 blocktypes = [] |
940 blocktypes = [] |
1088 for category in BlockTypes[:-1] + PluginTypes: |
941 for category in BlockTypes + self.PluginTypes: |
1089 cat = {"name" : category["name"], "list" : []} |
942 cat = {"name" : category["name"], "list" : []} |
1090 for block in category["list"]: |
943 for block in category["list"]: |
1091 if block["type"] == "function": |
944 if block["type"] == "function": |
1092 cat["list"].append(block) |
945 cat["list"].append(block) |
1093 if len(cat["list"]) > 0: |
946 if len(cat["list"]) > 0: |
1094 blocktypes.append(cat) |
947 blocktypes.append(cat) |
1095 else: |
948 else: |
1096 blocktypes = [category for category in BlockTypes[:-1] + PluginTypes] |
949 blocktypes = [category for category in BlockTypes + self.PluginTypes] |
1097 if self.Project: |
950 if self.Project: |
1098 blocktypes.append({"name" : "User-defined POUs", "list": []}) |
951 blocktypes.append({"name" : "User-defined POUs", "list": self.Project.GetCustomBlockTypes(name)}) |
1099 for blocktype in BlockTypes[-1]["list"]: |
|
1100 if blocktype["name"] != name and not self.PouIsUsedBy(name, blocktype["name"]) and not (type == "function" and blocktype["type"] != "function"): |
|
1101 blocktypes[-1]["list"].append(blocktype) |
|
1102 return blocktypes |
952 return blocktypes |
1103 |
953 |
1104 # Return Function Block types checking for recursion |
954 # Return Function Block types checking for recursion |
1105 def GetFunctionBlockTypes(self, tagname = ""): |
955 def GetFunctionBlockTypes(self, tagname = ""): |
1106 name = "" |
|
1107 type = None |
|
1108 if self.Project: |
|
1109 words = tagname.split("::") |
|
1110 if words[0] in ["P","T","A"]: |
|
1111 name = words[1] |
|
1112 type = self.GetPouType(name) |
|
1113 blocktypes = [] |
956 blocktypes = [] |
1114 for category in BlockTypes[:-1]: |
957 for category in BlockTypes + self.PluginTypes: |
1115 for block in category["list"]: |
958 for block in category["list"]: |
1116 if block["type"] != "function": |
959 if block["type"] != "function": |
1117 blocktypes.append(block["name"]) |
960 blocktypes.append(block["name"]) |
1118 if self.Project: |
961 if self.Project: |
1119 for blocktype in BlockTypes[-1]["list"]: |
962 name = "" |
1120 if blocktype["name"] != name and not self.PouIsUsedBy(name, blocktype["name"]) and not (type == "function" and blocktype["type"] != "function"): |
963 words = tagname.split("::") |
1121 blocktypes.append(blocktype["name"]) |
964 if words[0] in ["P","T","A"]: |
|
965 name = words[1] |
|
966 blocktypes.extend(self.Project.GetCustomFunctionBlockTypes(name)) |
1122 return blocktypes |
967 return blocktypes |
1123 |
968 |
1124 # Return Block types checking for recursion |
969 # Return Block types checking for recursion |
1125 def GetBlockResource(self): |
970 def GetBlockResource(self): |
1126 blocktypes = [] |
971 blocktypes = [] |
1127 for category in BlockTypes[:-1]: |
972 for category in BlockTypes[:-1]: |
1128 for blocktype in category["list"]: |
973 for blocktype in category["list"]: |
1129 if blocktype["type"] == "program": |
974 if blocktype["type"] == "program": |
1130 blocktypes.append(blocktype["name"]) |
975 blocktypes.append(blocktype["name"]) |
1131 if self.Project: |
976 if self.Project: |
1132 for pou in self.Project.getpous(): |
977 blocktypes.extend(self.Project.GetCustomBlockResource()) |
1133 if pou.getpouType() == "program": |
|
1134 blocktypes.append(pou.getname()) |
|
1135 return blocktypes |
978 return blocktypes |
1136 |
979 |
1137 # Return Data Types checking for recursion |
980 # Return Data Types checking for recursion |
1138 def GetDataTypes(self, tagname = "", basetypes = True): |
981 def GetDataTypes(self, tagname = "", basetypes = True): |
1139 if basetypes: |
982 if basetypes: |
1140 datatypes = self.GetBaseTypes() |
983 datatypes = self.GetBaseTypes() |
1141 else: |
984 else: |
1142 datatypes = [] |
985 datatypes = [] |
1143 if self.Project: |
986 if self.Project: |
|
987 name = "" |
1144 words = tagname.split("::") |
988 words = tagname.split("::") |
1145 if words[0] in ["D"]: |
989 if words[0] in ["D"]: |
1146 name = words[1] |
990 name = words[1] |
1147 else: |
991 datatypes.extend(self.Project.GetCustomDataTypes(name)) |
1148 name = "" |
|
1149 for datatype in self.Project.getdataTypes(): |
|
1150 datatype_name = datatype.getname() |
|
1151 if datatype_name != name and not self.DataTypeIsUsedBy(name, datatype_name): |
|
1152 datatypes.append(datatype_name) |
|
1153 return datatypes |
992 return datatypes |
1154 |
993 |
1155 # Return Base Type of given possible derived type |
994 # Return Base Type of given possible derived type |
1156 def GetBaseType(self, type): |
995 def GetBaseType(self, type): |
1157 return GetBaseType(type) |
996 if self.Project: |
|
997 return self.Project.GetBaseType(type) |
|
998 return None |
1158 |
999 |
1159 # Return Base Types |
1000 # Return Base Types |
1160 def GetBaseTypes(self): |
1001 def GetBaseTypes(self): |
1161 return [value for value, parent in TypeHierarchy_list if not value.startswith("ANY")] |
1002 return [value for value in TypeHierarchy.keys() if not value.startswith("ANY")] |
1162 |
1003 |
|
1004 def IsOfType(self, type, reference): |
|
1005 if self.Project: |
|
1006 return self.Project.IsOfType(type, reference) |
|
1007 elif reference is None: |
|
1008 return True |
|
1009 elif type == reference: |
|
1010 return True |
|
1011 else: |
|
1012 if type in TypeHierarchy: |
|
1013 return self.IsOfType(TypeHierarchy[type], reference) |
|
1014 return None |
|
1015 |
|
1016 def IsEndType(self, type): |
|
1017 if type is not None: |
|
1018 return not type.startswith("ANY") |
|
1019 return True |
|
1020 |
|
1021 def GetDataTypeRange(self, type): |
|
1022 if self.Project: |
|
1023 return self.Project.GetDataTypeRange(type) |
|
1024 elif type in DataTypeRange: |
|
1025 return DataTypeRange[type] |
|
1026 return None |
|
1027 |
1163 # Return Subrange types |
1028 # Return Subrange types |
1164 def GetSubrangeTypes(self): |
1029 def GetSubrangeBaseTypes(self, exclude): |
1165 return [value for value, range in DataTypeRange_list] |
1030 if self.Project: |
1166 |
1031 return self.Project.GetSubrangeBaseTypes(exclude) |
|
1032 return [] |
|
1033 |
1167 # Return Enumerated Values |
1034 # Return Enumerated Values |
1168 def GetEnumeratedDataValues(self): |
1035 def GetEnumeratedDataValues(self): |
1169 return EnumeratedDataValues |
1036 if self.Project: |
|
1037 return self.Project.GetEnumeratedDataTypeValues() |
|
1038 return [] |
1170 |
1039 |
1171 #------------------------------------------------------------------------------- |
1040 #------------------------------------------------------------------------------- |
1172 # Project Element tag name computation functions |
1041 # Project Element tag name computation functions |
1173 #------------------------------------------------------------------------------- |
1042 #------------------------------------------------------------------------------- |
1174 |
1043 |