PLCControler.py
changeset 0 b622defdfd98
child 2 93bc4c2cf376
equal deleted inserted replaced
-1:000000000000 0:b622defdfd98
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 
       
     4 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
       
     5 #based on the plcopen standard. 
       
     6 #
       
     7 #Copyright (C): Edouard TISSERANT and Laurent BESSARD
       
     8 #
       
     9 #See COPYING file for copyrights details.
       
    10 #
       
    11 #This library is free software; you can redistribute it and/or
       
    12 #modify it under the terms of the GNU Lesser General Public
       
    13 #License as published by the Free Software Foundation; either
       
    14 #version 2.1 of the License, or (at your option) any later version.
       
    15 #
       
    16 #This library is distributed in the hope that it will be useful,
       
    17 #but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    18 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    19 #Lesser General Public License for more details.
       
    20 #
       
    21 #You should have received a copy of the GNU Lesser General Public
       
    22 #License along with this library; if not, write to the Free Software
       
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    24 
       
    25 from minixsv import pyxsval
       
    26 import cPickle
       
    27 import os,sys,re
       
    28 
       
    29 from plcopen import plcopen
       
    30 from plcopen.structures import *
       
    31 from graphics.GraphicCommons import *
       
    32 from PLCGenerator import *
       
    33 
       
    34 [ITEM_UNEDITABLE, ITEM_PROJECT, ITEM_POU, ITEM_CLASS, ITEM_VARIABLE,
       
    35  ITEM_TRANSITION, ITEM_ACTION, ITEM_CONFIGURATION, ITEM_RESOURCE] = range(9)
       
    36 
       
    37 #-------------------------------------------------------------------------------
       
    38 #                         Undo Buffer for PLCOpenEditor
       
    39 #-------------------------------------------------------------------------------
       
    40 
       
    41 # Length of the buffer
       
    42 UNDO_BUFFER_LENGTH = 20
       
    43 
       
    44 """
       
    45 Class implementing a buffer of changes made on the current editing Object Dictionary
       
    46 """
       
    47 class UndoBuffer:
       
    48 
       
    49     # Constructor initialising buffer
       
    50     def __init__(self, currentstate, issaved = False):
       
    51         self.Buffer = []
       
    52         self.CurrentIndex = -1
       
    53         self.MinIndex = -1
       
    54         self.MaxIndex = -1
       
    55         # if current state is defined
       
    56         if currentstate:
       
    57             self.CurrentIndex = 0
       
    58             self.MinIndex = 0
       
    59             self.MaxIndex = 0
       
    60         # Initialising buffer with currentstate at the first place
       
    61         for i in xrange(UNDO_BUFFER_LENGTH):
       
    62             if i == 0:
       
    63                 self.Buffer.append(currentstate)
       
    64             else:
       
    65                 self.Buffer.append(None)
       
    66         # Initialising index of state saved
       
    67         if issaved:
       
    68             self.LastSave = 0
       
    69         else:
       
    70             self.LastSave = -1
       
    71     
       
    72     # Add a new state in buffer
       
    73     def Buffering(self, currentstate):
       
    74         self.CurrentIndex = (self.CurrentIndex + 1) % UNDO_BUFFER_LENGTH
       
    75         self.Buffer[self.CurrentIndex] = currentstate
       
    76         # Actualising buffer limits
       
    77         self.MaxIndex = self.CurrentIndex
       
    78         if self.MinIndex == self.CurrentIndex:
       
    79             # If the removed state was the state saved, there is no state saved in the buffer
       
    80             if self.LastSave == self.MinIndex:
       
    81                 self.LastSave = -1
       
    82             self.MinIndex = (self.MinIndex + 1) % UNDO_BUFFER_LENGTH
       
    83         self.MinIndex = max(self.MinIndex, 0)
       
    84     
       
    85     # Return current state of buffer
       
    86     def Current(self):
       
    87         return self.Buffer[self.CurrentIndex]
       
    88     
       
    89     # Change current state to previous in buffer and return new current state
       
    90     def Previous(self):
       
    91         if self.CurrentIndex != self.MinIndex:
       
    92             self.CurrentIndex = (self.CurrentIndex - 1) % UNDO_BUFFER_LENGTH
       
    93             return self.Buffer[self.CurrentIndex]
       
    94         return None
       
    95     
       
    96     # Change current state to next in buffer and return new current state
       
    97     def Next(self):
       
    98         if self.CurrentIndex != self.MaxIndex:
       
    99             self.CurrentIndex = (self.CurrentIndex + 1) % UNDO_BUFFER_LENGTH
       
   100             return self.Buffer[self.CurrentIndex]
       
   101         return None
       
   102     
       
   103     # Return True if current state is the first in buffer
       
   104     def IsFirst(self):
       
   105         return self.CurrentIndex == self.MinIndex
       
   106     
       
   107     # Return True if current state is the last in buffer
       
   108     def IsLast(self):
       
   109         return self.CurrentIndex == self.MaxIndex
       
   110 
       
   111     # Note that current state is saved
       
   112     def CurrentSaved(self):
       
   113         self.LastSave = self.CurrentIndex
       
   114         
       
   115     # Return True if current state is saved
       
   116     def IsCurrentSaved(self):
       
   117         return self.LastSave == self.CurrentIndex
       
   118 
       
   119 
       
   120 #-------------------------------------------------------------------------------
       
   121 #                           Controler for PLCOpenEditor
       
   122 #-------------------------------------------------------------------------------
       
   123 
       
   124 """
       
   125 Class which controls the operations made on the plcopen model and answers to view requests
       
   126 """
       
   127 class PLCControler:
       
   128     
       
   129     # Create a new PLCControler
       
   130     def __init__(self):
       
   131         self.LastNewIndex = 0
       
   132         self.Reset()
       
   133     
       
   134     # Reset PLCControler internal variables
       
   135     def Reset(self):
       
   136         self.Project = None
       
   137         self.ProjectBuffer = None
       
   138         self.FilePath = ""
       
   139         self.FileName = ""
       
   140         self.ElementsOpened = []
       
   141         self.CurrentElementEditing = None
       
   142         self.RefreshPouUsingTree()
       
   143         self.RefreshBlockTypes()
       
   144 
       
   145     def GetQualifierTypes(self):
       
   146         return plcopen.QualifierList
       
   147 
       
   148 
       
   149 #-------------------------------------------------------------------------------
       
   150 #                         Project management functions
       
   151 #-------------------------------------------------------------------------------
       
   152 
       
   153     # Return if a project is opened
       
   154     def HasOpenedProject(self):
       
   155         return self.Project != None
       
   156 
       
   157     # Create a new project by replacing the current one
       
   158     def CreateNewProject(self, name):
       
   159         # Create the project
       
   160         self.Project = plcopen.project()
       
   161         self.Project.setName(name)
       
   162         # Initialize the project buffer
       
   163         self.ProjectBuffer = UndoBuffer(self.Copy(self.Project))
       
   164     
       
   165     # Change project name
       
   166     def SetProjectName(self, name):
       
   167         self.Project.setName(name)
       
   168     
       
   169     # Return project name
       
   170     def GetProjectName(self):
       
   171         return self.Project.getName()
       
   172     
       
   173     # Return project pou names
       
   174     def GetProjectPouNames(self):
       
   175         return [pou.getName() for pou in self.Project.getPous()]
       
   176     
       
   177     # Return project pou names
       
   178     def GetProjectConfigNames(self):
       
   179         return [config.getName() for config in self.Project.getConfigurations()]
       
   180     
       
   181     # Return file path if project is an open file
       
   182     def GetFilePath(self):
       
   183         return self.FilePath
       
   184     
       
   185     # Return file name and point out if file is up to date
       
   186     def GetFilename(self):
       
   187         if self.ProjectBuffer.IsCurrentSaved():
       
   188             return self.FileName
       
   189         else:
       
   190             return "~%s~"%self.FileName
       
   191     
       
   192     # Change file path and save file name or create a default one if file path not defined
       
   193     def SetFilePath(self, filepath):
       
   194         self.FilePath = filepath
       
   195         if filepath == "":
       
   196             self.LastNewIndex += 1
       
   197             self.FileName = "Unnamed%d"%self.LastNewIndex
       
   198         else:
       
   199             self.FileName = os.path.splitext(os.path.basename(filepath))[0]
       
   200     
       
   201     # Change project properties
       
   202     def SetProjectProperties(self, values):
       
   203         self.Project.setFileHeader(values)
       
   204     
       
   205     # Return project properties
       
   206     def GetProjectProperties(self):
       
   207         return self.Project.getFileHeader()
       
   208     
       
   209     # Return project informations
       
   210     def GetProjectInfos(self):
       
   211         if self.Project:
       
   212             infos = {"name": self.Project.getName(), "type": ITEM_PROJECT}
       
   213             pou_types = {"function": {"name": "Functions", "type": ITEM_UNEDITABLE, "values":[]},
       
   214                          "functionBlock": {"name": "Function Blocks", "type": ITEM_UNEDITABLE, "values":[]},
       
   215                          "program": {"name": "Programs", "type": ITEM_UNEDITABLE, "values":[]}}
       
   216             for pou in self.Project.getPous():
       
   217                 pou_type = pou.getPouType().getValue()
       
   218                 pou_infos = {"name": pou.getName(), "type": ITEM_POU}
       
   219                 var_types = {"Input": {"name": "Input", "type": ITEM_CLASS, "values": []},
       
   220                          "Output": {"name": "Output", "type": ITEM_CLASS, "values": []},
       
   221                          "InOut": {"name": "InOut", "type": ITEM_CLASS, "values": []},
       
   222                          "External": {"name": "External", "type": ITEM_CLASS, "values": []},
       
   223                          "Local": {"name": "Local", "type": ITEM_CLASS, "values": []},
       
   224                          "Temp": {"name": "Temp", "type": ITEM_CLASS, "values": []},
       
   225                          "Global": {"name": "Global", "type": ITEM_CLASS, "values": []}}
       
   226                 for var in self.GetPouInterfaceVars(pou):
       
   227                     var_values = {"name": var["Name"], "type": ITEM_VARIABLE, "values": []}
       
   228                     if var["Class"] in var_types.keys():
       
   229                         var_types[var["Class"]]["values"].append(var_values)
       
   230                 pou_values = []
       
   231                 pou_values.append({"name": "Interface", "type": ITEM_CLASS, 
       
   232                     "values": [var_types["Input"], var_types["Output"], var_types["InOut"], var_types["External"]]})
       
   233                 pou_values.append({"name": "Variables", "type": ITEM_CLASS, 
       
   234                     "values": [var_types["Local"], var_types["Temp"]]})
       
   235                 if pou_type == "program":
       
   236                     pou_values.append(var_types["Global"])
       
   237                 if pou.getBodyType() == "SFC":
       
   238                     transitions = []
       
   239                     for transition in pou.getTransitionList():
       
   240                         transitions.append({"name": transition.getName(), "type": ITEM_TRANSITION, "values": []})
       
   241                     pou_values.append({"name": "Transitions", "type": ITEM_UNEDITABLE, "values": transitions})
       
   242                     actions = []
       
   243                     for action in pou.getActionList():
       
   244                         actions.append({"name": action.getName(), "type": ITEM_ACTION, "values": []})
       
   245                     pou_values.append({"name": "Actions", "type": ITEM_UNEDITABLE, "values": actions})
       
   246                 if pou_type in pou_types:
       
   247                     pou_infos["values"] = pou_values
       
   248                     pou_types[pou_type]["values"].append(pou_infos)
       
   249             configurations = {"name": "Configurations", "type": ITEM_UNEDITABLE, "values": []}
       
   250             for config in self.Project.getConfigurations():
       
   251                 config_name = config.getName()
       
   252                 config_infos = {"name": config_name, "type": ITEM_CONFIGURATION, "values": []}
       
   253                 config_vars = {"name": "Global", "type": ITEM_CLASS, "values": []}
       
   254                 for var in self.GetConfigurationGlobalVars(config_name):
       
   255                     var_values = {"name": var["Name"], "type": ITEM_VARIABLE, "values": []}
       
   256                     config_vars["values"].append(var_values)
       
   257                 resources = {"name": "Resources", "type": ITEM_UNEDITABLE, "values": []}
       
   258                 for resource in config.getResource():
       
   259                     resource_name = resource.getName()
       
   260                     resource_infos = {"name": resource_name, "type": ITEM_RESOURCE, "values": []}
       
   261                     resource_vars = {"name": "Global", "type": ITEM_CLASS, "values": []}
       
   262                     for var in self.GetConfigurationResourceGlobalVars(config_name, resource_name):
       
   263                         var_values = {"name": var["Name"], "type": ITEM_VARIABLE, "values": []}
       
   264                         resource_vars["values"].append(var_values)
       
   265                     resource_infos["values"].append(resource_vars)
       
   266                     resources["values"].append(resource_infos)
       
   267                 config_infos["values"] = [config_vars, resources]
       
   268                 configurations["values"].append(config_infos)
       
   269             infos["values"] = [{"name": "Properties", "type": ITEM_UNEDITABLE, "values": []},
       
   270                                pou_types["function"], pou_types["functionBlock"], 
       
   271                                pou_types["program"], configurations]
       
   272             return infos
       
   273         return None
       
   274 
       
   275     # Refresh the tree of user-defined pou cross-use
       
   276     def RefreshPouUsingTree(self):
       
   277         # Reset the tree of user-defined pou cross-use
       
   278         self.PouUsingTree = {}
       
   279         if self.Project:
       
   280             pous = self.Project.getPous()
       
   281             # Reference all the user-defined pou names and initialize the tree of 
       
   282             # user-defined pou cross-use
       
   283             pounames = [pou.getName() for pou in pous]
       
   284             for name in pounames:
       
   285                 self.PouUsingTree[name] = []
       
   286             # Analyze each pou 
       
   287             for pou in pous:
       
   288                 name = pou.getName()
       
   289                 bodytype = pou.getBodyType()
       
   290                 # If pou is written in a graphical language
       
   291                 if bodytype in ["FBD","LD","SFC"]:
       
   292                     # Analyze each instance of the pou
       
   293                     for instance in pou.getInstances():
       
   294                         if isinstance(instance, plcopen.block):
       
   295                             typename = instance.getTypeName()
       
   296                             # Update tree if there is a cross-use
       
   297                             if typename in pounames and name not in self.PouUsingTree[typename]:
       
   298                                  self.PouUsingTree[typename].append(name)
       
   299                 # If pou is written in a textual language
       
   300                 elif bodytype in ["IL", "ST"]:
       
   301                     text = pou.getText()
       
   302                     # Search if each pou is mentioned in the pou text
       
   303                     for typename in pounames:
       
   304                         typename_model = re.compile("[ \t\n]%s[ \t\n]"%typename)
       
   305                         # Update tree if there is a cross-use
       
   306                         if typename != name and typename_model.search(text):
       
   307                             self.PouUsingTree[typename].append(name)
       
   308 
       
   309     # Return if pou given by name is used by another pou
       
   310     def PouIsUsed(self, name):
       
   311         if name in self.PouUsingTree:
       
   312             return len(self.PouUsingTree[name]) > 0
       
   313         return False
       
   314 
       
   315     # Return if pou given by name is directly or undirectly used by the reference pou
       
   316     def PouIsUsedBy(self, name, reference):
       
   317         if name in self.PouUsingTree:
       
   318             list = self.PouUsingTree[name]
       
   319             # Test if pou is directly used by reference
       
   320             if reference in list:
       
   321                 return True
       
   322             else:
       
   323                 # Test if pou is undirectly used by reference, by testing if pous 
       
   324                 # that directly use pou is directly or undirectly used by reference
       
   325                 used = False
       
   326                 for element in list:
       
   327                     used |= self.PouIsUsedBy(element, reference)
       
   328                 return used
       
   329         return False
       
   330 
       
   331     def GenerateProgram(self):
       
   332         if self.Project:
       
   333             program = GenerateCurrentProgram(self.Project)
       
   334             programfile = open("test.st", "w")
       
   335             programfile.write(program)
       
   336             programfile.close()
       
   337 
       
   338 #-------------------------------------------------------------------------------
       
   339 #                        Project Pous management functions
       
   340 #-------------------------------------------------------------------------------
       
   341     
       
   342     # Add a Pou to Project
       
   343     def ProjectAddPou(self, name, pou_type, body_type):
       
   344         # Add the pou to project
       
   345         self.Project.appendPou(name, pou_type, body_type)
       
   346         self.RefreshPouUsingTree()
       
   347         self.RefreshBlockTypes()
       
   348     
       
   349     # Remove a pou from project
       
   350     def ProjectRemovePou(self, name):
       
   351         removed = None
       
   352         # Search if the pou removed is currently opened
       
   353         for i, pou in enumerate(self.ElementsOpened):
       
   354             if pou == name:
       
   355                 removed = i
       
   356         # If found, remove pou from list of opened pous and actualize current edited
       
   357         if removed != None:
       
   358             self.ElementsOpened.pop(removed)
       
   359             if self.CurrentElementEditing > removed:
       
   360                 self.CurrentElementEditing -= 1
       
   361             if len(self.ElementsOpened) > 0:
       
   362                 self.CurrentElementEditing = max(0, min(self.CurrentElementEditing, len(self.ElementsOpened) - 1))
       
   363             else:
       
   364                 self.CurrentElementEditing = None
       
   365         # Remove pou from project
       
   366         self.Project.removePou(name)
       
   367         self.RefreshPouUsingTree()
       
   368         self.RefreshBlockTypes()
       
   369     
       
   370     # Add a configuration to Project
       
   371     def ProjectAddConfiguration(self, name):
       
   372         self.Project.addConfiguration(name)
       
   373         self.RefreshPouUsingTree()
       
   374         self.RefreshBlockTypes()
       
   375     
       
   376     # Remove a configuration from project
       
   377     def ProjectRemoveConfiguration(self, name):
       
   378         self.Project.removeConfiguration(name)
       
   379         self.RefreshPouUsingTree()
       
   380         self.RefreshBlockTypes()
       
   381     
       
   382     # Add a resource to a configuration of the Project
       
   383     def ProjectAddConfigurationResource(self, config, name):
       
   384         self.Project.addConfigurationResource(config, name)
       
   385         self.RefreshPouUsingTree()
       
   386         self.RefreshBlockTypes()
       
   387     
       
   388     # Remove a resource from a configuration of the project
       
   389     def ProjectRemoveConfigurationResource(self, config, name):
       
   390         self.Project.removeConfigurationResource(config, name)
       
   391         self.RefreshPouUsingTree()
       
   392         self.RefreshBlockTypes()
       
   393     
       
   394     # Add a Transition to a Project Pou
       
   395     def ProjectAddPouTransition(self, pou_name, transition_name, transition_type):
       
   396         pou = self.Project.getPou(pou_name)
       
   397         pou.addTransition(transition_name, transition_type)
       
   398     
       
   399     # Add a Transition to a Project Pou
       
   400     def ProjectAddPouAction(self, pou_name, action_name, action_type):
       
   401         pou = self.Project.getPou(pou_name)
       
   402         pou.addAction(action_name, action_type)
       
   403         
       
   404     # Change the name of a pou
       
   405     def ChangePouName(self, old_name, new_name):
       
   406         # Found the pou corresponding to old name and change its name to new name
       
   407         pou = self.Project.getPou(old_name)
       
   408         pou.setName(new_name)
       
   409         # If pou is currently opened, change its name in the list of opened pous
       
   410         if old_name in self.ElementsOpened:
       
   411             idx = self.ElementsOpened.index(old_name)
       
   412             self.ElementsOpened[idx] = new_name
       
   413         self.RefreshPouUsingTree()
       
   414         self.RefreshBlockTypes()
       
   415     
       
   416     # Change the name of a pou transition
       
   417     def ChangePouTransitionName(self, pou_name, old_name, new_name):
       
   418         # Found the pou transition corresponding to old name and change its name to new name
       
   419         pou = self.Project.getPou(pou_name)
       
   420         transition = pou.getTransition(old_name)
       
   421         transition.setName(new_name)
       
   422         # If pou transition is currently opened, change its name in the list of opened elements
       
   423         old_computedname = self.ComputePouTransitionName(pou_name, old_name)
       
   424         new_computedname = self.ComputePouTransitionName(pou_name, new_name)
       
   425         if old_computedname in self.ElementsOpened:
       
   426             idx = self.ElementsOpened.index(old_computedname)
       
   427             self.ElementsOpened[idx] = new_computedname
       
   428     
       
   429     # Change the name of a pou action
       
   430     def ChangePouActionName(self, pou_name, old_name, new_name):
       
   431         # Found the pou action corresponding to old name and change its name to new name
       
   432         pou = self.Project.getPou(pou_name)
       
   433         action = pou.getAction(old_name)
       
   434         action.setName(new_name)
       
   435         # If pou action is currently opened, change its name in the list of opened elements
       
   436         old_computedname = self.ComputePouActionName(pou_name, old_name)
       
   437         new_computedname = self.ComputePouActionName(pou_name, new_name)
       
   438         if old_computedname in self.ElementsOpened:
       
   439             idx = self.ElementsOpened.index(old_computedname)
       
   440             self.ElementsOpened[idx] = new_computedname
       
   441 
       
   442     # Change the name of a configuration
       
   443     def ChangeConfigurationName(self, old_name, new_name):
       
   444         # Found the configuration corresponding to old name and change its name to new name
       
   445         configuration = self.Project.getConfiguration(old_name)
       
   446         configuration.setName(new_name)
       
   447         # If configuration is currently opened, change its name in the list of opened elements
       
   448         for idx, element in enumerate(self.ElementsOpened):
       
   449             self.ElementsOpened[idx] = element.replace(old_name, new_name)
       
   450 
       
   451     # Change the name of a configuration resource
       
   452     def ChangeConfigurationResourceName(self, config_name, old_name, new_name):
       
   453         # Found the resource corresponding to old name and change its name to new name
       
   454         resource = self.Project.getConfigurationResource(config_name)
       
   455         resource.setName(new_name)
       
   456         # If resource is currently opened, change its name in the list of opened elements
       
   457         old_computedname = self.ComputeConfigurationResourceName(config_name, old_name)
       
   458         new_computedname = self.ComputeConfigurationResourceName(config_name, new_name)
       
   459         if old_computedname in self.ElementsOpened:
       
   460             idx = self.ElementsOpened.index(old_computedname)
       
   461             self.ElementsOpened[idx] = new_computedname
       
   462     
       
   463     # Return the type of the pou given by its name
       
   464     def GetPouType(self, name):
       
   465         # Found the pou correponding to name and return its type
       
   466         pou = self.Project.getPou(name)
       
   467         return pou.pouType.getValue()
       
   468     
       
   469     # Return pous with SFC language
       
   470     def GetSFCPous(self):
       
   471         list = []
       
   472         if self.Project:
       
   473             for pou in self.Project.getPous():
       
   474                 if pou.getBodyType() == "SFC":
       
   475                     list.append(pou.getName())
       
   476         return list
       
   477     
       
   478     # Return the body language of the pou given by its name
       
   479     def GetPouBodyType(self, name):
       
   480         # Found the pou correponding to name and return its body language
       
   481         pou = self.Project.getPou(name)
       
   482         return pou.getBodyType()
       
   483     
       
   484     # Return the body language of the transition given by its name
       
   485     def GetTransitionBodyType(self, pou_name, pou_transition):
       
   486         # Found the pou correponding to name and return its body language
       
   487         pou = self.Project.getPou(pou_name)
       
   488         transition = pou.getTransition(pou_transition)
       
   489         return transition.getBodyType()
       
   490     
       
   491     # Return the body language of the pou given by its name
       
   492     def GetActionBodyType(self, pou_name, pou_action):
       
   493         # Found the pou correponding to name and return its body language
       
   494         pou = self.Project.getPou(pou_name)
       
   495         action = pou.getAction(pou_action)
       
   496         return action.getBodyType()
       
   497     
       
   498     # Extract varlists from a list of vars
       
   499     def ExtractVarLists(self, vars):
       
   500         varlist_list = []
       
   501         current_varlist = None
       
   502         current_type = None
       
   503         for var in vars:
       
   504             if current_type != (var["Class"], var["Retain"], var["Constant"]):
       
   505                 current_type = (var["Class"], var["Retain"], var["Constant"])
       
   506                 current_varlist = plcopen.varList()
       
   507                 varlist_list.append((var["Class"], current_varlist))
       
   508                 if var["Retain"] == "Yes":
       
   509                     varlist.setRetain(True)
       
   510                 if var["Constant"] == "Yes":
       
   511                     varlist.setConstant(True)
       
   512             # Create variable and change its properties
       
   513             tempvar = plcopen.varListPlain_variable()
       
   514             tempvar.setName(var["Name"])
       
   515             var_type = plcopen.dataType()
       
   516             var_type.setValue(var["Type"])
       
   517             tempvar.setType(var_type)
       
   518             if var["Initial Value"] != "":
       
   519                 value = plcopen.value()
       
   520                 value.setValue(var["Initial Value"])
       
   521                 tempvar.setInitialValue(value)
       
   522             if var["Location"] != "":
       
   523                 tempvar.setAddress(var["Location"])
       
   524             # Add variable to varList
       
   525             current_varlist.appendVariable(tempvar)
       
   526         return varlist_list
       
   527 
       
   528     # Replace the configuration globalvars by those given
       
   529     def SetConfigurationGlobalVars(self, name, vars):
       
   530         # Found the configuration corresponding to name
       
   531         configuration = self.Project.getConfiguration(name)
       
   532         if configuration:
       
   533             # Set configuration global vars
       
   534             configuration.setGlobalVars([])
       
   535             for vartype, varlist in self.ExtractVarLists(vars):
       
   536                 configuration.globalVars.append(varlist)
       
   537         self.RefreshBlockTypes()
       
   538 
       
   539     # Return the configuration globalvars
       
   540     def GetConfigurationGlobalVars(self, name):
       
   541         vars = []
       
   542         # Found the configuration corresponding to name
       
   543         configuration = self.Project.getConfiguration(name)
       
   544         if configuration:
       
   545             # Extract variables from every varLists
       
   546             for varlist in configuration.getGlobalVars():
       
   547                 for var in varlist.getVariable():
       
   548                     tempvar = {"Name":var.getName(),"Class":"Global","Type":var.getType().getValue(),
       
   549                         "Location":var.getAddress()}
       
   550                     initial = var.getInitialValue()
       
   551                     if initial:
       
   552                         tempvar["Initial Value"] = initial.getValue()
       
   553                     else:
       
   554                         tempvar["Initial Value"] = ""
       
   555                     if varlist.getRetain():
       
   556                         tempvar["Retain"] = "Yes"
       
   557                     else:
       
   558                         tempvar["Retain"] = "No"
       
   559                     if varlist.getConstant():
       
   560                         tempvar["Constant"] = "Yes"
       
   561                     else:
       
   562                         tempvar["Constant"] = "No"
       
   563                     vars.append(tempvar)
       
   564         return vars
       
   565 
       
   566     # Replace the resource globalvars by those given
       
   567     def SetConfigurationResourceGlobalVars(self, config_name, name, vars):
       
   568         # Found the resource corresponding to name
       
   569         resource = self.Project.getConfigurationResource(config_name, name)
       
   570         # Set resource global vars
       
   571         if resource:
       
   572             resource.setGlobalVars([])
       
   573             for vartype, varlist in self.ExtractVarLists(vars):
       
   574                 resource.globalVars.append(varlist)
       
   575         self.RefreshBlockTypes()
       
   576 
       
   577     # Return the resource globalvars
       
   578     def GetConfigurationResourceGlobalVars(self, config_name, name):
       
   579         vars = []
       
   580         # Found the resource corresponding to name
       
   581         resource = self.Project.getConfigurationResource(config_name, name)
       
   582         if resource:
       
   583             # Extract variables from every varLists
       
   584             for varlist in resource.getGlobalVars():
       
   585                 for var in varlist.getVariable():
       
   586                     tempvar = {"Name":var.getName(),"Class":"Global","Type":var.getType().getValue(),
       
   587                         "Location":var.getAddress()}
       
   588                     initial = var.getInitialValue()
       
   589                     if initial:
       
   590                         tempvar["Initial Value"] = initial.getValue()
       
   591                     else:
       
   592                         tempvar["Initial Value"] = ""
       
   593                     if varlist.getRetain():
       
   594                         tempvar["Retain"] = "Yes"
       
   595                     else:
       
   596                         tempvar["Retain"] = "No"
       
   597                     if varlist.getConstant():
       
   598                         tempvar["Constant"] = "Yes"
       
   599                     else:
       
   600                         tempvar["Constant"] = "No"
       
   601                     vars.append(tempvar)
       
   602         return vars
       
   603     
       
   604     # Return the interface of the pou given by its name
       
   605     def GetPouInterfaceVarsByName(self, name):
       
   606         # Found the pou correponding to name and return the interface
       
   607         return self.GetPouInterfaceVars(self.Project.getPou(name))
       
   608     
       
   609     # Return the interface for the given pou
       
   610     def GetPouInterfaceVars(self, pou):
       
   611         vars = []
       
   612         # Verify that the pou has an interface
       
   613         if pou.interface:
       
   614             # Extract variables from every varLists
       
   615             for type, varlist in pou.getVars():
       
   616                 for var in varlist.getVariable():
       
   617                     tempvar = {"Name":var.getName(),"Class":type,"Type":var.getType().getValue(),
       
   618                         "Location":var.getAddress()}
       
   619                     initial = var.getInitialValue()
       
   620                     if initial:
       
   621                         tempvar["Initial Value"] = initial.getValue()
       
   622                     else:
       
   623                         tempvar["Initial Value"] = ""
       
   624                     if varlist.getRetain():
       
   625                         tempvar["Retain"] = "Yes"
       
   626                     else:
       
   627                         tempvar["Retain"] = "No"
       
   628                     if varlist.getConstant():
       
   629                         tempvar["Constant"] = "Yes"
       
   630                     else:
       
   631                         tempvar["Constant"] = "No"
       
   632                     vars.append(tempvar)
       
   633         return vars
       
   634 
       
   635     # Replace the Pou interface by the one given
       
   636     def SetPouInterfaceVars(self, name, vars):
       
   637         # Found the pou corresponding to name and add interface if there isn't one yet
       
   638         pou = self.Project.getPou(name)
       
   639         if not pou.interface:
       
   640             pou.interface = plcopen.pou_interface()
       
   641         # Set Pou interface
       
   642         pou.setVars(self.ExtractVarLists(vars))
       
   643         self.RefreshBlockTypes()
       
   644 
       
   645     # Replace the return type of the pou given by its name (only for functions)
       
   646     def SetPouInterfaceReturnType(self, name, type):
       
   647         pou = self.Project.getPou(name)
       
   648         if not pou.interface:
       
   649             pou.interface = plcopen.pou_interface()
       
   650         # If there isn't any return type yet, add it
       
   651         return_type = pou.interface.getReturnType()
       
   652         if not return_type:
       
   653             return_type = plcopen.dataType()
       
   654             pou.interface.setReturnType(return_type)
       
   655         # Change return type
       
   656         return_type.setValue(type)
       
   657         self.RefreshBlockTypes()
       
   658     
       
   659     # Return the return type of the pou given by its name
       
   660     def GetPouInterfaceReturnTypeByName(self, name):
       
   661         # Found the pou correponding to name and return the return type
       
   662         return self.GetPouInterfaceReturnType(self.Project.getPou(name))
       
   663     
       
   664     # Return the return type of the given pou
       
   665     def GetPouInterfaceReturnType(self, pou):
       
   666         # Verify that the pou has an interface
       
   667         if pou.interface:
       
   668             # Return the return type if there is one
       
   669             return_type = pou.interface.getReturnType()
       
   670             if return_type:
       
   671                 return return_type.getValue()
       
   672         return None
       
   673 
       
   674     # Update Block types with user-defined pou added
       
   675     def RefreshBlockTypes(self):
       
   676         if BlockTypes[-1]["name"] == "User-defined POUs":
       
   677             BlockTypes[-1]["list"] = []
       
   678         else:
       
   679             BlockTypes.append({"name" : "User-defined POUs", "list": []})
       
   680         if self.Project:
       
   681             for pou in self.Project.getPous():
       
   682                 pou_name = pou.getName()
       
   683                 pou_type = pou.pouType.getValue()
       
   684                 if pou_type != "program":
       
   685                     block_infos = {"name" : pou_name, "type" : pou_type, "extensible" : False,
       
   686                                    "inputs" : [], "outputs" : [], "comment" : ""}
       
   687                     if pou.getInterface():
       
   688                         for type, varlist in pou.getVars():
       
   689                             if type == "InOut":
       
   690                                 for var in varlist.getVariable():
       
   691                                     block_infos["inputs"].append((var.getName(),var.getType().getValue(),"none"))
       
   692                                     block_infos["outputs"].append((var.getName(),var.getType().getValue(),"none"))
       
   693                             elif type == "Input":
       
   694                                 for var in varlist.getVariable():
       
   695                                     block_infos["inputs"].append((var.getName(),var.getType().getValue(),"none"))
       
   696                             elif type == "Output":
       
   697                                 for var in varlist.getVariable():
       
   698                                     block_infos["outputs"].append((var.getName(),var.getType().getValue(),"none"))
       
   699                         return_type = pou.interface.getReturnType()
       
   700                         if return_type:
       
   701                             block_infos["outputs"].append(("",return_type.getValue(),"none"))
       
   702                     if pou.getBodyType() in ["FBD","LD","SFC"]:
       
   703                         for instance in pou.getInstances():
       
   704                             if isinstance(instance, plcopen.comment):
       
   705                                 block_infos["comment"] = instance.getContentText()
       
   706                     BlockTypes[-1]["list"].append(block_infos)
       
   707 
       
   708     # Return Block types checking for recursion
       
   709     def GetBlockTypes(self):
       
   710         if self.CurrentElementEditing != None:
       
   711             current_name = self.ElementsOpened[self.CurrentElementEditing]
       
   712             words = current_name.split("::")
       
   713             if len(words) == 1:
       
   714                 name = current_name
       
   715             else:
       
   716                 name = words[1]
       
   717             blocktypes = [category for category in BlockTypes[:-1]]
       
   718             blocktypes.append({"name" : "User-defined POUs", "list": []})
       
   719             if self.Project:
       
   720                 pou = self.Project.getPou(name)
       
   721                 name = pou.getName()
       
   722                 type = pou.pouType.getValue()
       
   723                 for blocktype in BlockTypes[-1]["list"]:
       
   724                     if blocktype["name"] != name and not self.PouIsUsedBy(name, blocktype["name"]) and not (type == "function" and blocktype["type"] == "functionBlock"):
       
   725                         blocktypes[-1]["list"].append(blocktype)
       
   726             return blocktypes
       
   727         return []
       
   728 
       
   729     # Return Block types checking for recursion
       
   730     def GetBlockResource(self):
       
   731         blocktypes = []
       
   732         for category in BlockTypes[:-1]:
       
   733             for blocktype in category["list"]:
       
   734                 if blocktype["type"] != "function":
       
   735                     blocktypes.append(blocktype["name"])
       
   736         if self.Project:
       
   737             for pou in self.Project.getPous():
       
   738                 if pou.pouType.getValue() != "function":
       
   739                     blocktypes.append(pou.getName())
       
   740         return blocktypes
       
   741 
       
   742 #-------------------------------------------------------------------------------
       
   743 #                       Project opened Pous management functions
       
   744 #-------------------------------------------------------------------------------
       
   745     
       
   746     # Return the list of pou names
       
   747     def GetElementsOpenedNames(self):
       
   748         names = []
       
   749         for pou_name in self.ElementsOpened:
       
   750             words = pou_name.split("::")
       
   751             if len(words) == 1:
       
   752                 names.append(pou_name)
       
   753             else:
       
   754                 names.append("%s-%s"%(words[1],words[2]))
       
   755         return names
       
   756     
       
   757     # Compute a pou transition name
       
   758     def ComputePouTransitionName(self, pou, transition):
       
   759         return "T::%s::%s" % (pou, transition)
       
   760     
       
   761     # Compute a pou action name
       
   762     def ComputePouActionName(self, pou, action):
       
   763         return "A::%s::%s" % (pou, action)
       
   764 
       
   765     # Compute a pou  name
       
   766     def ComputeConfigurationResourceName(self, config, resource):
       
   767         return "R::%s::%s" % (config, resource)
       
   768     
       
   769     # Open a pou by giving its name
       
   770     def OpenElementEditing(self, name):
       
   771         # If pou not opened yet
       
   772         if name not in self.ElementsOpened:
       
   773             # Add pou name to list of pou opened and make it current editing
       
   774             self.ElementsOpened.append(name)
       
   775             self.CurrentElementEditing = len(self.ElementsOpened) - 1
       
   776             return self.CurrentElementEditing
       
   777         return None
       
   778 
       
   779     # Open a pou transition by giving pou and transition names
       
   780     def OpenPouTransitionEditing(self, pou, transition):
       
   781         return self.OpenElementEditing(self.ComputePouTransitionName(pou, transition))
       
   782 
       
   783     # Open a pou action by giving pou and action names
       
   784     def OpenPouActionEditing(self, pou, action):
       
   785         return self.OpenElementEditing(self.ComputePouActionName(pou, action))
       
   786 
       
   787     # Open a configuration resource by giving configuration and resource names
       
   788     def OpenConfigurationResourceEditing(self, config, resource):
       
   789         return self.OpenElementEditing(self.ComputeConfigurationResourceName(config, resource))
       
   790 
       
   791     # Return if pou given by name is opened
       
   792     def IsElementEditing(self, name):
       
   793         return name in self.ElementsOpened
       
   794 
       
   795     # Return if pou transition given by pou and transition names is opened
       
   796     def IsPouTransitionEditing(self, pou, transition):
       
   797         return self.ComputePouTransitionName(pou, transition) in self.ElementsOpened
       
   798 
       
   799     # Return if pou action given by pou and action names is opened
       
   800     def IsPouActionEditing(self, pou, action):
       
   801         return self.ComputePouActionName(pou, action) in self.ElementsOpened
       
   802 
       
   803     # Return if pou action given by pou and action names is opened
       
   804     def IsConfigurationResourceEditing(self, pou, action):
       
   805         return self.ComputeConfigurationResourceName(config, resource) in self.ElementsOpened
       
   806 
       
   807     # Close current pou editing
       
   808     def CloseElementEditing(self):
       
   809         # Remove pou from list of pou opened
       
   810         self.ElementsOpened.pop(self.CurrentElementEditing)
       
   811         # Update index of current pou editing
       
   812         if len(self.ElementsOpened) > 0:
       
   813             self.CurrentElementEditing = min(self.CurrentElementEditing, len(self.ElementsOpened) - 1)
       
   814         else:
       
   815             self.CurrentElementEditing = None
       
   816 
       
   817     # Change current pou editing for pou given by name
       
   818     def ChangeElementEditing(self, name):
       
   819         # Verify that pou is opened
       
   820         if name in self.ElementsOpened:
       
   821             # Change current pou editing
       
   822             self.CurrentElementEditing = self.ElementsOpened.index(name)
       
   823             return self.CurrentElementEditing
       
   824         return None
       
   825 
       
   826     # Change current pou editing for transition given by pou and transition names
       
   827     def ChangePouTransitionEditing(self, pou, transition):
       
   828         return self.ChangeElementEditing(self.ComputePouTransitionName(pou, transition))
       
   829 
       
   830     # Change current pou editing for action given by pou and action names
       
   831     def ChangePouActionEditing(self, pou, action):
       
   832         return self.ChangeElementEditing(self.ComputePouActionName(pou, action))
       
   833 
       
   834     # Change current pou editing for action given by configuration and resource names
       
   835     def ChangeConfigurationResourceEditing(self, config, resource):
       
   836         return self.ChangeElementEditing(self.ComputeConfigurationResourceName(config, resource))
       
   837 
       
   838 #-------------------------------------------------------------------------------
       
   839 #                       Project opened Pous management functions
       
   840 #-------------------------------------------------------------------------------
       
   841 
       
   842     # Return current pou editing
       
   843     def GetCurrentElementEditing(self):
       
   844         # Verify that there's one editing and return it
       
   845         if self.CurrentElementEditing != None:
       
   846             name = self.ElementsOpened[self.CurrentElementEditing]
       
   847             words = name.split("::")
       
   848             if len(words) == 1:
       
   849                 return self.Project.getPou(name)
       
   850             else:
       
   851                 if words[0] in ['T', 'A']:
       
   852                     pou = self.Project.getPou(words[1])
       
   853                     if words[0] == 'T':
       
   854                         return pou.getTransition(words[2])
       
   855                     elif words[0] == 'A':
       
   856                         return pou.getAction(words[2])
       
   857                 elif words[0] == 'R':
       
   858                     result = self.Project.getConfigurationResource(words[1], words[2])
       
   859                     return result
       
   860         return None
       
   861     
       
   862     # Return current pou editing name
       
   863     def GetCurrentElementEditingName(self):
       
   864         # Verify that there's one editing and return its name
       
   865         if self.CurrentElementEditing != None:
       
   866             name = self.ElementsOpened[self.CurrentElementEditing]
       
   867             words = name.split("::")
       
   868             if len(words) == 1:
       
   869                 return name
       
   870             else:
       
   871                 return words[2]
       
   872         return None
       
   873     
       
   874     # Replace the index of current pou editing by the one given
       
   875     def RefreshCurrentElementEditing(self, index):
       
   876         self.CurrentElementEditing = index
       
   877 
       
   878     # Return language in which current pou editing is written
       
   879     def GetCurrentElementEditingBodyType(self):
       
   880         if self.CurrentElementEditing != None:
       
   881             name = self.ElementsOpened[self.CurrentElementEditing]
       
   882             words = name.split("::")
       
   883             if len(words) == 1:
       
   884                 return self.GetPouBodyType(name)
       
   885             else:
       
   886                 if words[0] == 'T':
       
   887                     return self.GetTransitionBodyType(words[1], words[2])
       
   888                 elif words[0] == 'A':
       
   889                     return self.GetActionBodyType(words[1], words[2])
       
   890         return None
       
   891 
       
   892     # Return the variables of the current pou editing
       
   893     def GetCurrentElementEditingInterfaceVars(self):
       
   894         if self.CurrentElementEditing != None:
       
   895             current_name = self.ElementsOpened[self.CurrentElementEditing]
       
   896             words = current_name.split("::")
       
   897             if len(words) == 1:
       
   898                 pou = self.Project.getPou(current_name)
       
   899                 return self.GetPouInterfaceVars(pou)
       
   900             else:
       
   901                 pou = self.Project.getPou(words[1])
       
   902                 return self.GetPouInterfaceVars(pou)
       
   903         return []
       
   904 
       
   905     # Return the return type of the current pou editing
       
   906     def GetCurrentElementEditingInterfaceReturnType(self):
       
   907         if self.CurrentElementEditing != None:
       
   908             current_name = self.ElementsOpened[self.CurrentElementEditing]
       
   909             words = current_name.split("::")
       
   910             if len(words) == 1:
       
   911                 pou = self.Project.getPou(current_name)
       
   912                 return self.GetPouInterfaceReturnType(pou)
       
   913             elif words[0] == 'T':
       
   914                 return "BOOL"
       
   915         return None
       
   916     
       
   917     # Change the text of the current pou editing
       
   918     def SetCurrentElementEditingText(self, text):
       
   919         if self.CurrentElementEditing != None:
       
   920             self.GetCurrentElementEditing().setText(text)
       
   921             self.RefreshPouUsingTree()
       
   922     
       
   923     # Return the current pou editing text
       
   924     def GetCurrentElementEditingText(self):
       
   925         if self.CurrentElementEditing != None:
       
   926             return self.GetCurrentElementEditing().getText()
       
   927         return ""
       
   928 
       
   929     # Return the current pou editing transitions
       
   930     def GetCurrentElementEditingTransitions(self):
       
   931         if self.CurrentElementEditing != None:
       
   932             pou = self.GetCurrentElementEditing()
       
   933             if pou.getBodyType() == "SFC":
       
   934                 transitions = []
       
   935                 for transition in pou.getTransitionList():
       
   936                     transitions.append(transition.getName())
       
   937                 return transitions
       
   938         return []
       
   939 
       
   940     # Return the current pou editing transitions
       
   941     def GetCurrentElementEditingActions(self):
       
   942         if self.CurrentElementEditing != None:
       
   943             pou = self.GetCurrentElementEditing()
       
   944             if pou.getBodyType() == "SFC":
       
   945                 actions = []
       
   946                 for action in pou.getActionList():
       
   947                     actions.append(action.getName())
       
   948                 return actions
       
   949         return []
       
   950 
       
   951     # Return the current pou editing informations
       
   952     def GetCurrentElementEditingInstanceInfos(self, id = None, exclude = []):
       
   953         infos = {}
       
   954         # if id is defined
       
   955         if id != None:
       
   956             instance = self.GetCurrentElementEditing().getInstance(id)
       
   957         else:
       
   958             instance = self.GetCurrentElementEditing().getRandomInstance(exclude)
       
   959         if instance:
       
   960             if id != None:
       
   961                 infos["id"] = id
       
   962             else:
       
   963                 infos["id"] = instance.getLocalId() 
       
   964             infos["x"] = instance.getX()
       
   965             infos["y"] = instance.getY()
       
   966             infos["height"] = instance.getHeight()
       
   967             infos["width"] = instance.getWidth()
       
   968             if isinstance(instance, plcopen.block):
       
   969                 infos["name"] = instance.getInstanceName()
       
   970                 infos["type"] = instance.getTypeName()
       
   971                 infos["connectors"] = {"inputs":[],"outputs":[]}
       
   972                 for variable in instance.inputVariables.getVariable():
       
   973                     connector = {}
       
   974                     connector["position"] = variable.connectionPointIn.getRelPosition()
       
   975                     connector["negated"] = variable.getNegated()
       
   976                     connector["edge"] = variable.getConnectorEdge()
       
   977                     connector["links"] = []
       
   978                     connections = variable.connectionPointIn.getConnections()
       
   979                     if connections:
       
   980                         for link in connections:
       
   981                             dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()}
       
   982                             connector["links"].append(dic)
       
   983                     infos["connectors"]["inputs"].append(connector)
       
   984                 for variable in instance.outputVariables.getVariable():
       
   985                     connector = {}
       
   986                     connector["position"] = variable.connectionPointOut.getRelPosition()
       
   987                     connector["negated"] = variable.getNegated()
       
   988                     connector["edge"] = variable.getConnectorEdge()
       
   989                     infos["connectors"]["outputs"].append(connector)
       
   990             elif isinstance(instance, plcopen.inVariable):
       
   991                 infos["name"] = instance.getExpression()
       
   992                 infos["value_type"] = self.GetPouVarValueType(self.GetCurrentElementEditing(), infos["name"])
       
   993                 infos["type"] = "input"
       
   994                 infos["connector"] = {}
       
   995                 infos["connector"]["position"] = instance.connectionPointOut.getRelPosition()
       
   996                 infos["connector"]["negated"] = instance.getNegated()
       
   997                 infos["connector"]["edge"] = instance.getConnectorEdge()
       
   998             elif isinstance(instance, plcopen.outVariable):
       
   999                 infos["name"] = instance.getExpression()
       
  1000                 infos["value_type"] = self.GetPouVarValueType(self.GetCurrentElementEditing(), infos["name"])
       
  1001                 infos["type"] = "output"
       
  1002                 infos["connector"] = {}
       
  1003                 infos["connector"]["position"] = instance.connectionPointIn.getRelPosition()
       
  1004                 infos["connector"]["negated"] = instance.getNegated()
       
  1005                 infos["connector"]["edge"] = instance.getConnectorEdge()
       
  1006                 infos["connector"]["links"] = []
       
  1007                 connections = instance.connectionPointIn.getConnections()
       
  1008                 if connections:
       
  1009                     for link in connections:
       
  1010                         dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()}
       
  1011                         infos["connector"]["links"].append(dic)
       
  1012             elif isinstance(instance, plcopen.inOutVariable):
       
  1013                 infos["name"] = instance.getExpression()
       
  1014                 infos["value_type"] = self.GetPouVarValueType(self.GetCurrentElementEditing(), infos["name"])
       
  1015                 infos["type"] = "inout"
       
  1016                 infos["connectors"] = {"input":{},"output":{}}
       
  1017                 infos["connectors"]["output"]["position"] = instance.connectionPointOut.getRelPosition()
       
  1018                 infos["connectors"]["output"]["negated"] = instance.getNegatedOut()
       
  1019                 infos["connectors"]["output"]["edge"] = instance.getOutputEdge()
       
  1020                 infos["connectors"]["input"]["position"] = instance.connectionPointIn.getRelPosition()
       
  1021                 infos["connectors"]["input"]["negated"] = instance.getNegatedIn()
       
  1022                 infos["connectors"]["input"]["edge"] = instance.getInputEdge()
       
  1023                 infos["connectors"]["input"]["links"] = []
       
  1024                 connections = instance.connectionPointIn.getConnections()
       
  1025                 if connections:
       
  1026                     for link in connections:
       
  1027                         dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()}
       
  1028                         infos["connectors"]["input"]["links"].append(dic)
       
  1029             elif isinstance(instance, plcopen.continuation):
       
  1030                 infos["name"] = instance.getName()
       
  1031                 infos["value_type"] = self.GetPouVarValueType(self.GetCurrentElementEditing(), infos["name"])
       
  1032                 infos["type"] = "continuation"
       
  1033                 infos["connector"] = {}
       
  1034                 infos["connector"]["position"] = instance.connectionPointOut.getRelPosition()
       
  1035             elif isinstance(instance, plcopen.connector):
       
  1036                 infos["name"] = instance.getName()
       
  1037                 infos["value_type"] = self.GetPouVarValueType(self.GetCurrentElementEditing(), infos["name"])
       
  1038                 infos["type"] = "connection"
       
  1039                 infos["connector"] = {}
       
  1040                 infos["connector"]["position"] = instance.connectionPointIn.getRelPosition()
       
  1041                 infos["connector"]["links"] = []
       
  1042                 connections = instance.connectionPointIn.getConnections()
       
  1043                 if connections:
       
  1044                     for link in connections:
       
  1045                         dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()}
       
  1046                         infos["connector"]["links"].append(dic)
       
  1047             elif isinstance(instance, plcopen.comment):
       
  1048                 infos["type"] = "comment"
       
  1049                 infos["content"] = instance.getContentText()
       
  1050             elif isinstance(instance, plcopen.leftPowerRail):
       
  1051                 infos["type"] = "leftPowerRail"
       
  1052                 infos["connectors"] = []
       
  1053                 for connection in instance.getConnectionPointOut():
       
  1054                     connector = {}
       
  1055                     connector["position"] = connection.getRelPosition()
       
  1056                     infos["connectors"].append(connector)
       
  1057             elif isinstance(instance, plcopen.rightPowerRail):
       
  1058                 infos["type"] = "rightPowerRail"
       
  1059                 infos["connectors"] = []
       
  1060                 for connection in instance.getConnectionPointIn():
       
  1061                     connector = {}
       
  1062                     connector["position"] = connection.getRelPosition()
       
  1063                     connector["links"] = []
       
  1064                     for link in connection.getConnections():
       
  1065                         dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()}
       
  1066                         connector["links"].append(dic)
       
  1067                     infos["connectors"].append(connector)
       
  1068             elif isinstance(instance, plcopen.contact):
       
  1069                 infos["type"] = "contact"
       
  1070                 infos["name"] = instance.getVariable()
       
  1071                 infos["negated"] = instance.getNegated()
       
  1072                 infos["edge"] = instance.getContactEdge()
       
  1073                 infos["connectors"] = {"input":{},"output":{}}
       
  1074                 infos["connectors"]["input"]["position"] = instance.connectionPointIn.getRelPosition()
       
  1075                 infos["connectors"]["input"]["links"] = []
       
  1076                 connections = instance.connectionPointIn.getConnections()
       
  1077                 if connections:
       
  1078                     for link in connections:
       
  1079                         dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()}
       
  1080                         infos["connectors"]["input"]["links"].append(dic)
       
  1081                 infos["connectors"]["output"]["position"] = instance.connectionPointOut.getRelPosition()
       
  1082             elif isinstance(instance, plcopen.coil):
       
  1083                 infos["type"] = "coil"
       
  1084                 infos["name"] = instance.getVariable()
       
  1085                 infos["negated"] = instance.getNegated()
       
  1086                 infos["storage"] = instance.getCoilStorage()
       
  1087                 infos["connectors"] = {"input":{},"output":{}}
       
  1088                 infos["connectors"]["input"]["position"] = instance.connectionPointIn.getRelPosition()
       
  1089                 infos["connectors"]["input"]["links"] = []
       
  1090                 connections = instance.connectionPointIn.getConnections()
       
  1091                 if connections:
       
  1092                     for link in connections:
       
  1093                         dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()}
       
  1094                         infos["connectors"]["input"]["links"].append(dic)
       
  1095                 infos["connectors"]["output"]["position"] = instance.connectionPointOut.getRelPosition()
       
  1096             elif isinstance(instance, plcopen.step):
       
  1097                 infos["type"] = "step"
       
  1098                 infos["name"] = instance.getName()
       
  1099                 infos["initial"] = instance.getInitialStep()
       
  1100                 infos["connectors"] = {}
       
  1101                 if instance.connectionPointIn:
       
  1102                     infos["connectors"]["input"] = {}
       
  1103                     infos["connectors"]["input"]["position"] = instance.connectionPointIn.getRelPosition()
       
  1104                     infos["connectors"]["input"]["links"] = []
       
  1105                     connections = instance.connectionPointIn.getConnections()
       
  1106                     if connections:
       
  1107                         for link in connections:
       
  1108                             dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()}
       
  1109                             infos["connectors"]["input"]["links"].append(dic)
       
  1110                 if instance.connectionPointOut:
       
  1111                     infos["connectors"]["output"] = {"position" : instance.connectionPointOut.getRelPosition()}
       
  1112                 if instance.connectionPointOutAction:
       
  1113                     infos["connectors"]["action"] = {"position" : instance.connectionPointOutAction.getRelPosition()}
       
  1114             elif isinstance(instance, plcopen.transition):
       
  1115                 infos["type"] = "transition"
       
  1116                 condition = instance.getConditionContent()
       
  1117                 infos["condition_type"] = condition["type"]
       
  1118                 infos["condition"] = condition["value"]
       
  1119                 infos["connectors"] = {"input":{},"output":{}}
       
  1120                 infos["connectors"]["input"]["position"] = instance.connectionPointIn.getRelPosition()
       
  1121                 infos["connectors"]["input"]["links"] = []
       
  1122                 connections = instance.connectionPointIn.getConnections()
       
  1123                 if connections:
       
  1124                     for link in connections:
       
  1125                         dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()}
       
  1126                         infos["connectors"]["input"]["links"].append(dic)
       
  1127                 infos["connectors"]["output"]["position"] = instance.connectionPointOut.getRelPosition()
       
  1128             elif isinstance(instance, (plcopen.selectionDivergence, plcopen.simultaneousDivergence)):
       
  1129                 if isinstance(instance, plcopen.selectionDivergence):
       
  1130                     infos["type"] = "selectionDivergence"
       
  1131                 else:
       
  1132                     infos["type"] = "simultaneousDivergence"
       
  1133                 infos["connectors"] = {"inputs":[],"outputs":[]}
       
  1134                 connector = {}
       
  1135                 connector["position"] = instance.connectionPointIn.getRelPosition()
       
  1136                 connector["links"] = []
       
  1137                 connections = instance.connectionPointIn.getConnections()
       
  1138                 if connections:
       
  1139                     for link in connections:
       
  1140                         dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()}
       
  1141                         connector["links"].append(dic)
       
  1142                 infos["connectors"]["inputs"].append(connector)
       
  1143                 for sequence in instance.getConnectionPointOut():
       
  1144                     connector = {}
       
  1145                     connector["position"] = sequence.getRelPosition()
       
  1146                     infos["connectors"]["outputs"].append(connector)
       
  1147             elif isinstance(instance, (plcopen.selectionConvergence, plcopen.simultaneousConvergence)):
       
  1148                 if isinstance(instance, plcopen.selectionConvergence):
       
  1149                     infos["type"] = "selectionConvergence"
       
  1150                 else:
       
  1151                     infos["type"] = "simultaneousConvergence"
       
  1152                 infos["connectors"] = {"inputs":[],"outputs":[]}
       
  1153                 for sequence in instance.getConnectionPointIn():
       
  1154                     connector = {}
       
  1155                     connector["position"] = sequence.getRelPosition()
       
  1156                     connector["links"] = []
       
  1157                     connections = sequence.getConnections()
       
  1158                     if connections:
       
  1159                         for link in connections:
       
  1160                             dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()}
       
  1161                             connector["links"].append(dic)
       
  1162                     infos["connectors"]["inputs"].append(connector)
       
  1163                 connector = {}
       
  1164                 connector["position"] = instance.connectionPointOut.getRelPosition()
       
  1165                 infos["connectors"]["outputs"].append(connector)
       
  1166             elif isinstance(instance, plcopen.jumpStep):
       
  1167                 infos["type"] = "jump"
       
  1168                 infos["target"] = instance.getTargetName()
       
  1169                 infos["connector"] = {}
       
  1170                 infos["connector"]["position"] = instance.connectionPointIn.getRelPosition()
       
  1171                 infos["connector"]["links"] = []
       
  1172                 connections = instance.connectionPointIn.getConnections()
       
  1173                 if connections:
       
  1174                     for link in connections:
       
  1175                         dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()}
       
  1176                         infos["connector"]["links"].append(dic)
       
  1177             elif isinstance(instance, plcopen.actionBlock):
       
  1178                 infos["type"] = "actionBlock"
       
  1179                 infos["actions"] = instance.getActions()
       
  1180                 infos["connector"] = {}
       
  1181                 infos["connector"]["position"] = instance.connectionPointIn.getRelPosition()
       
  1182                 infos["connector"]["links"] = []
       
  1183                 connections = instance.connectionPointIn.getConnections()
       
  1184                 if connections:
       
  1185                     for link in connections:
       
  1186                         dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()}
       
  1187                         infos["connector"]["links"].append(dic)
       
  1188             return infos
       
  1189         return False
       
  1190     
       
  1191     # Return the variable type of the given pou
       
  1192     def GetPouVarValueType(self, pou, varname):
       
  1193         for type, varlist in pou.getVars():
       
  1194             for var in varlist.getVariable():
       
  1195                 if var.getName() == varname:
       
  1196                     return var.getType()
       
  1197         return ""
       
  1198     
       
  1199     def SetConnectionWires(self, connection, connector):
       
  1200         wires = connector.GetWires()
       
  1201         idx = 0
       
  1202         for wire, handle in wires:
       
  1203             points = wire.GetPoints(handle != 0)
       
  1204             if handle == 0:
       
  1205                 refLocalId = wire.GetConnectedId(-1)
       
  1206             else:
       
  1207                 refLocalId = wire.GetConnectedId(0)
       
  1208             if refLocalId != None:
       
  1209                 connection.addConnection()
       
  1210                 connection.setConnectionId(idx, refLocalId)
       
  1211                 connection.setConnectionPoints(idx, points)
       
  1212                 idx += 1
       
  1213     
       
  1214     def AddCurrentElementEditingBlock(self, id):
       
  1215         block = plcopen.block()
       
  1216         block.setLocalId(id)
       
  1217         self.GetCurrentElementEditing().addInstance("block", block)
       
  1218         self.RefreshPouUsingTree()
       
  1219     
       
  1220     def SetCurrentElementEditingBlockInfos(self, id, infos):
       
  1221         block = self.GetCurrentElementEditing().getInstance(id)
       
  1222         for param, value in infos.items():
       
  1223             if param == "name":
       
  1224                 block.setInstanceName(value)
       
  1225             elif param == "type":
       
  1226                 block.setTypeName(value)
       
  1227             elif param == "height":
       
  1228                 block.setHeight(value)
       
  1229             elif param == "width":
       
  1230                 block.setWidth(value)
       
  1231             elif param == "x":
       
  1232                 block.setX(value)
       
  1233             elif param == "y":
       
  1234                 block.setY(value)
       
  1235             elif param == "connectors":
       
  1236                 block.inputVariables.setVariable([])
       
  1237                 block.outputVariables.setVariable([])
       
  1238                 for connector in value["inputs"]:
       
  1239                     variable = plcopen.inputVariables_variable()
       
  1240                     variable.setFormalParameter(connector.GetName())
       
  1241                     if connector.IsNegated():
       
  1242                         variable.setNegated(True)
       
  1243                     if connector.GetEdge() != "none":
       
  1244                         variable.setConnectorEdge(connector.GetEdge())
       
  1245                     position = connector.GetRelPosition()
       
  1246                     variable.connectionPointIn.setRelPosition(position.x, position.y)
       
  1247                     self.SetConnectionWires(variable.connectionPointIn, connector)
       
  1248                     block.inputVariables.appendVariable(variable)
       
  1249                 for connector in value["outputs"]:
       
  1250                     variable = plcopen.outputVariables_variable()
       
  1251                     variable.setFormalParameter(connector.GetName())
       
  1252                     if connector.IsNegated():
       
  1253                         variable.setNegated(True)
       
  1254                     if connector.GetEdge() != "none":
       
  1255                         variable.setConnectorEdge(connector.GetEdge())
       
  1256                     position = connector.GetRelPosition()
       
  1257                     variable.addConnectionPointOut()
       
  1258                     variable.connectionPointOut.setRelPosition(position.x, position.y)
       
  1259                     block.outputVariables.appendVariable(variable)
       
  1260         self.RefreshPouUsingTree()
       
  1261         
       
  1262     def AddCurrentElementEditingVariable(self, id, type):
       
  1263         if type == INPUT:
       
  1264             name = "inVariable"
       
  1265             variable = plcopen.inVariable()
       
  1266         elif type == OUTPUT:
       
  1267             name = "outVariable"
       
  1268             variable = plcopen.outVariable()
       
  1269         elif type == INOUT:
       
  1270             name = "inOutVariable"
       
  1271             variable = plcopen.inOutVariable()
       
  1272         variable.setLocalId(id)
       
  1273         self.GetCurrentElementEditing().addInstance(name, variable)
       
  1274         
       
  1275     def SetCurrentElementEditingVariableInfos(self, id, infos):
       
  1276         variable = self.GetCurrentElementEditing().getInstance(id)
       
  1277         for param, value in infos.items():
       
  1278             if param == "name":
       
  1279                 variable.setExpression(value)    
       
  1280             elif param == "height":
       
  1281                 variable.setHeight(value)
       
  1282             elif param == "width":
       
  1283                 variable.setWidth(value)
       
  1284             elif param == "x":
       
  1285                 variable.setX(value)
       
  1286             elif param == "y":
       
  1287                 variable.setY(value)
       
  1288             elif param == "connectors":
       
  1289                 if isinstance(variable, plcopen.inVariable):
       
  1290                     if value["output"].IsNegated():
       
  1291                         variable.setNegated(True)
       
  1292                     if value["output"].GetEdge() != "none":
       
  1293                         variable.setConnectorEdge(value["output"].GetEdge())
       
  1294                     position = value["output"].GetRelPosition()
       
  1295                     variable.addConnectionPointOut()
       
  1296                     variable.connectionPointOut.setRelPosition(position.x, position.y)
       
  1297                 elif isinstance(variable, plcopen.outVariable):
       
  1298                     if value["input"].IsNegated():
       
  1299                         variable.setNegated(True)
       
  1300                     if value["input"].GetEdge() != "none":
       
  1301                         variable.setConnectorEdge(value["input"].GetEdge())
       
  1302                     position = value["input"].GetRelPosition()
       
  1303                     variable.addConnectionPointIn()
       
  1304                     variable.connectionPointIn.setRelPosition(position.x, position.y)
       
  1305                     self.SetConnectionWires(variable.connectionPointIn, value["input"])
       
  1306                 elif isinstance(variable, plcopen.inOutVariable):
       
  1307                     if value["input"].IsNegated():
       
  1308                         variable.setNegatedIn(True)
       
  1309                     if value["input"].GetEdge() != "none":
       
  1310                         variable.setInputEdge(value["input"].GetEdge())
       
  1311                     if value["output"].IsNegated():
       
  1312                         variable.setNegatedOut(True)
       
  1313                     if value["output"].GetEdge() != "none":
       
  1314                         variable.setOutputEdge(value["output"].GetEdge())
       
  1315                     position = value["output"].GetRelPosition()
       
  1316                     variable.addConnectionPointOut()
       
  1317                     variable.connectionPointOut.setRelPosition(position.x, position.y)
       
  1318                     position = value["input"].GetRelPosition()
       
  1319                     variable.addConnectionPointIn()
       
  1320                     variable.connectionPointIn.setRelPosition(position.x, position.y)
       
  1321                     self.SetConnectionWires(variable.connectionPointIn, value["input"])
       
  1322 
       
  1323 
       
  1324     def AddCurrentElementEditingConnection(self, id, type):
       
  1325         if type == CONNECTOR:
       
  1326             name = "connector"
       
  1327             connection = plcopen.connector()
       
  1328         elif type == CONTINUATION:
       
  1329             name = "continuation"
       
  1330             connection = plcopen.continuation()
       
  1331         connection.setLocalId(id)
       
  1332         self.GetCurrentElementEditing().addInstance(name, connection)
       
  1333         
       
  1334     def SetCurrentElementEditingConnectionInfos(self, id, infos):
       
  1335         connection = self.GetCurrentElementEditing().getInstance(id)
       
  1336         for param, value in infos.items():
       
  1337             if param == "name":
       
  1338                 connection.setName(value)    
       
  1339             elif param == "height":
       
  1340                 connection.setHeight(value)
       
  1341             elif param == "width":
       
  1342                 connection.setWidth(value)
       
  1343             elif param == "x":
       
  1344                 connection.setX(value)
       
  1345             elif param == "y":
       
  1346                 connection.setY(value)
       
  1347             elif param == "connector":
       
  1348                 position = value.GetRelPosition()
       
  1349                 if isinstance(connection, plcopen.continuation):
       
  1350                     connection.addConnectionPointOut()
       
  1351                     connection.connectionPointOut.setRelPosition(position.x, position.y)
       
  1352                 elif isinstance(connection, plcopen.connector):
       
  1353                     connection.addConnectionPointIn()
       
  1354                     connection.connectionPointIn.setRelPosition(position.x, position.y)
       
  1355                     self.SetConnectionWires(connection.connectionPointIn, value)
       
  1356 
       
  1357     def AddCurrentElementEditingComment(self, id):
       
  1358         comment = plcopen.comment()
       
  1359         comment.setLocalId(id)
       
  1360         self.GetCurrentElementEditing().addInstance("comment", comment)
       
  1361     
       
  1362     def SetCurrentElementEditingCommentInfos(self, id, infos):
       
  1363         comment = self.GetCurrentElementEditing().getInstance(id)
       
  1364         for param, value in infos.items():
       
  1365             if param == "content":
       
  1366                 comment.setContentText(value)
       
  1367             elif param == "height":
       
  1368                 comment.setHeight(value)
       
  1369             elif param == "width":
       
  1370                 comment.setWidth(value)
       
  1371             elif param == "x":
       
  1372                 comment.setX(value)
       
  1373             elif param == "y":
       
  1374                 comment.setY(value)
       
  1375 
       
  1376     def AddCurrentElementEditingPowerRail(self, id, type):
       
  1377         if type == LEFTRAIL:
       
  1378             name = "leftPowerRail"
       
  1379             powerrail = plcopen.leftPowerRail()
       
  1380         elif type == RIGHTRAIL:
       
  1381             name = "rightPowerRail"
       
  1382             powerrail = plcopen.rightPowerRail()
       
  1383         powerrail.setLocalId(id)
       
  1384         self.GetCurrentElementEditing().addInstance(name, powerrail)
       
  1385     
       
  1386     def SetCurrentElementEditingPowerRailInfos(self, id, infos):
       
  1387         powerrail = self.GetCurrentElementEditing().getInstance(id)
       
  1388         for param, value in infos.items():
       
  1389             if param == "height":
       
  1390                 powerrail.setHeight(value)
       
  1391             elif param == "width":
       
  1392                 powerrail.setWidth(value)
       
  1393             elif param == "x":
       
  1394                 powerrail.setX(value)
       
  1395             elif param == "y":
       
  1396                 powerrail.setY(value)
       
  1397             elif param == "connectors":
       
  1398                 if isinstance(powerrail, plcopen.leftPowerRail):
       
  1399                     powerrail.setConnectionPointOut([])
       
  1400                     for connector in value:
       
  1401                         position = connector.GetRelPosition()
       
  1402                         connection = plcopen.leftPowerRail_connectionPointOut()
       
  1403                         connection.setRelPosition(position.x, position.y)
       
  1404                         powerrail.connectionPointOut.append(connection)
       
  1405                 elif isinstance(powerrail, plcopen.rightPowerRail):
       
  1406                     powerrail.setConnectionPointIn([])
       
  1407                     for connector in value:
       
  1408                         position = connector.GetRelPosition()
       
  1409                         connection = plcopen.connectionPointIn()
       
  1410                         connection.setRelPosition(position.x, position.y)
       
  1411                         self.SetConnectionWires(connection, connector)
       
  1412                         powerrail.connectionPointIn.append(connection)
       
  1413 
       
  1414     def AddCurrentElementEditingContact(self, id):
       
  1415         contact = plcopen.contact()
       
  1416         contact.setLocalId(id)
       
  1417         self.GetCurrentElementEditing().addInstance("contact", contact)
       
  1418 
       
  1419     def SetCurrentElementEditingContactInfos(self, id, infos):
       
  1420         contact = self.GetCurrentElementEditing().getInstance(id)
       
  1421         for param, value in infos.items():
       
  1422             if param == "name":
       
  1423                 contact.setVariable(value)
       
  1424             elif param == "type":
       
  1425                 if value == CONTACT_NORMAL:
       
  1426                     contact.setNegated(False)
       
  1427                     contact.setContactEdge("none")
       
  1428                 elif value == CONTACT_REVERSE:
       
  1429                     contact.setNegated(True)
       
  1430                     contact.setContactEdge("none")
       
  1431                 elif value == CONTACT_RISING:
       
  1432                     contact.setNegated(False)
       
  1433                     contact.setContactEdge("rising")
       
  1434                 elif value == CONTACT_FALLING:
       
  1435                     contact.setNegated(False)
       
  1436                     contact.setContactEdge("falling")
       
  1437             elif param == "height":
       
  1438                 contact.setHeight(value)
       
  1439             elif param == "width":
       
  1440                 contact.setWidth(value)
       
  1441             elif param == "x":
       
  1442                 contact.setX(value)
       
  1443             elif param == "y":
       
  1444                 contact.setY(value)
       
  1445             elif param == "connectors":
       
  1446                 input_connector = value["input"]
       
  1447                 position = input_connector.GetRelPosition()
       
  1448                 contact.addConnectionPointIn()
       
  1449                 contact.connectionPointIn.setRelPosition(position.x, position.y)
       
  1450                 self.SetConnectionWires(contact.connectionPointIn, input_connector)
       
  1451                 output_connector = value["output"]
       
  1452                 position = output_connector.GetRelPosition()
       
  1453                 contact.addConnectionPointOut()
       
  1454                 contact.connectionPointOut.setRelPosition(position.x, position.y)
       
  1455 
       
  1456     def AddCurrentElementEditingCoil(self, id):
       
  1457         coil = plcopen.coil()
       
  1458         coil.setLocalId(id)
       
  1459         self.GetCurrentElementEditing().addInstance("coil", coil)
       
  1460 
       
  1461     def SetCurrentElementEditingCoilInfos(self, id, infos):
       
  1462         coil = self.GetCurrentElementEditing().getInstance(id)
       
  1463         for param, value in infos.items():
       
  1464             if param == "name":
       
  1465                 coil.setVariable(value)
       
  1466             elif param == "type":
       
  1467                 if value == COIL_NORMAL:
       
  1468                     coil.setNegated(False)
       
  1469                     coil.setCoilStorage("none")
       
  1470                 elif value == COIL_REVERSE:
       
  1471                     coil.setNegated(True)
       
  1472                     coil.setCoilStorage("none")
       
  1473                 elif value == COIL_SET:
       
  1474                     coil.setNegated(False)
       
  1475                     coil.setCoilStorage("set")
       
  1476                 elif value == COIL_RESET:
       
  1477                     coil.setNegated(False)
       
  1478                     coil.setCoilStorage("reset")
       
  1479             elif param == "height":
       
  1480                 coil.setHeight(value)
       
  1481             elif param == "width":
       
  1482                 coil.setWidth(value)
       
  1483             elif param == "x":
       
  1484                 coil.setX(value)
       
  1485             elif param == "y":
       
  1486                 coil.setY(value)
       
  1487             elif param == "connectors":
       
  1488                 input_connector = value["input"]
       
  1489                 position = input_connector.GetRelPosition()
       
  1490                 coil.addConnectionPointIn()
       
  1491                 coil.connectionPointIn.setRelPosition(position.x, position.y)
       
  1492                 self.SetConnectionWires(coil.connectionPointIn, input_connector)
       
  1493                 output_connector = value["output"]
       
  1494                 position = output_connector.GetRelPosition()
       
  1495                 coil.addConnectionPointOut()
       
  1496                 coil.connectionPointOut.setRelPosition(position.x, position.y)
       
  1497 
       
  1498     def AddCurrentElementEditingStep(self, id):
       
  1499         step = plcopen.step()
       
  1500         step.setLocalId(id)
       
  1501         self.GetCurrentElementEditing().addInstance("step", step)
       
  1502     
       
  1503     def SetCurrentElementEditingStepInfos(self, id, infos):
       
  1504         step = self.GetCurrentElementEditing().getInstance(id)
       
  1505         for param, value in infos.items():
       
  1506             if param == "name":
       
  1507                 step.setName(value)
       
  1508             elif param == "initial":
       
  1509                 step.setInitialStep(value)
       
  1510             elif param == "height":
       
  1511                 step.setHeight(value)
       
  1512             elif param == "width":
       
  1513                 step.setWidth(value)
       
  1514             elif param == "x":
       
  1515                 step.setX(value)
       
  1516             elif param == "y":
       
  1517                 step.setY(value)
       
  1518             elif param == "connectors":
       
  1519                 input_connector = value["input"]
       
  1520                 if input_connector:
       
  1521                     position = input_connector.GetRelPosition()
       
  1522                     step.addConnectionPointIn()
       
  1523                     step.connectionPointIn.setRelPosition(position.x, position.y)
       
  1524                     self.SetConnectionWires(step.connectionPointIn, input_connector)
       
  1525                 else:
       
  1526                     step.deleteConnectionPointIn()
       
  1527                 output_connector = value["output"]
       
  1528                 if output_connector:
       
  1529                     position = output_connector.GetRelPosition()
       
  1530                     step.addConnectionPointOut()
       
  1531                     step.connectionPointOut.setRelPosition(position.x, position.y)
       
  1532                 else:
       
  1533                     step.deleteConnectionPointOut()
       
  1534                 action_connector = value["action"]
       
  1535                 if action_connector:
       
  1536                     position = action_connector.GetRelPosition()
       
  1537                     step.addConnectionPointOutAction()
       
  1538                     step.connectionPointOutAction.setRelPosition(position.x, position.y)
       
  1539                 else:
       
  1540                     step.deleteConnectionPointOutAction()
       
  1541     
       
  1542     def AddCurrentElementEditingTransition(self, id):
       
  1543         transition = plcopen.transition()
       
  1544         transition.setLocalId(id)
       
  1545         self.GetCurrentElementEditing().addInstance("transition", transition)
       
  1546     
       
  1547     def SetCurrentElementEditingTransitionInfos(self, id, infos):
       
  1548         transition = self.GetCurrentElementEditing().getInstance(id)
       
  1549         for param, value in infos.items():
       
  1550             if param == "type" and "condition" in infos:
       
  1551                 transition.setConditionContent(value, infos["condition"])
       
  1552             elif param == "height":
       
  1553                 transition.setHeight(value)
       
  1554             elif param == "width":
       
  1555                 transition.setWidth(value)
       
  1556             elif param == "x":
       
  1557                 transition.setX(value)
       
  1558             elif param == "y":
       
  1559                 transition.setY(value)
       
  1560             elif param == "connectors":
       
  1561                 input_connector = value["input"]
       
  1562                 position = input_connector.GetRelPosition()
       
  1563                 transition.addConnectionPointIn()
       
  1564                 transition.connectionPointIn.setRelPosition(position.x, position.y)
       
  1565                 self.SetConnectionWires(transition.connectionPointIn, input_connector)
       
  1566                 output_connector = value["output"]
       
  1567                 position = output_connector.GetRelPosition()
       
  1568                 transition.addConnectionPointOut()
       
  1569                 transition.connectionPointOut.setRelPosition(position.x, position.y)
       
  1570     
       
  1571     def AddCurrentElementEditingDivergence(self, id, type):
       
  1572         if type == SELECTION_DIVERGENCE:
       
  1573             name = "selectionDivergence"
       
  1574             divergence = plcopen.selectionDivergence()
       
  1575         elif type == SELECTION_CONVERGENCE:
       
  1576             name = "selectionConvergence"
       
  1577             divergence = plcopen.selectionConvergence()
       
  1578         elif type == SIMULTANEOUS_DIVERGENCE:
       
  1579             name = "simultaneousDivergence"
       
  1580             divergence = plcopen.simultaneousDivergence()
       
  1581         elif type == SIMULTANEOUS_CONVERGENCE:
       
  1582             name = "simultaneousConvergence"
       
  1583             divergence = plcopen.simultaneousConvergence()
       
  1584         divergence.setLocalId(id)
       
  1585         self.GetCurrentElementEditing().addInstance(name, divergence)
       
  1586     
       
  1587     def SetCurrentElementEditingDivergenceInfos(self, id, infos):
       
  1588         divergence = self.GetCurrentElementEditing().getInstance(id)
       
  1589         for param, value in infos.items():
       
  1590             if param == "height":
       
  1591                 divergence.setHeight(value)
       
  1592             elif param == "width":
       
  1593                 divergence.setWidth(value)
       
  1594             elif param == "x":
       
  1595                 divergence.setX(value)
       
  1596             elif param == "y":
       
  1597                 divergence.setY(value)
       
  1598             elif param == "connectors":
       
  1599                 input_connectors = value["inputs"]
       
  1600                 if isinstance(divergence, (plcopen.selectionDivergence, plcopen.simultaneousDivergence)):
       
  1601                     position = input_connectors[0].GetRelPosition()
       
  1602                     divergence.addConnectionPointIn()
       
  1603                     divergence.connectionPointIn.setRelPosition(position.x, position.y)
       
  1604                     self.SetConnectionWires(divergence.connectionPointIn, input_connectors[0])
       
  1605                 else:
       
  1606                     divergence.setConnectionPointIn([])
       
  1607                     for input_connector in input_connectors:
       
  1608                         position = input_connector.GetRelPosition()
       
  1609                         if isinstance(divergence, plcopen.selectionConvergence):
       
  1610                             connection = plcopen.selectionConvergence_connectionPointIn()
       
  1611                         else:
       
  1612                             connection = plcopen.connectionPointIn()
       
  1613                         connection.setRelPosition(position.x, position.y)
       
  1614                         self.SetConnectionWires(connection, input_connector)
       
  1615                         divergence.appendConnectionPointIn(connection)
       
  1616                 output_connectors = value["outputs"]
       
  1617                 if isinstance(divergence, (plcopen.selectionConvergence, plcopen.simultaneousConvergence)):
       
  1618                     position = output_connectors[0].GetRelPosition()
       
  1619                     divergence.addConnectionPointOut()
       
  1620                     divergence.connectionPointOut.setRelPosition(position.x, position.y)
       
  1621                 else:
       
  1622                     divergence.setConnectionPointOut([])
       
  1623                     for output_connector in output_connectors:
       
  1624                         position = output_connector.GetRelPosition()
       
  1625                         if isinstance(divergence, plcopen.selectionDivergence):
       
  1626                             connection = plcopen.selectionDivergence_connectionPointOut()
       
  1627                         else:
       
  1628                             connection = plcopen.simultaneousDivergence_connectionPointOut()
       
  1629                         connection.setRelPosition(position.x, position.y)
       
  1630                         divergence.appendConnectionPointOut(connection)
       
  1631     
       
  1632     def AddCurrentElementEditingJump(self, id):
       
  1633         jump = plcopen.jumpStep()
       
  1634         jump.setLocalId(id)
       
  1635         self.GetCurrentElementEditing().addInstance("jumpStep", jump)
       
  1636     
       
  1637     def SetCurrentElementEditingJumpInfos(self, id, infos):
       
  1638         jump = self.GetCurrentElementEditing().getInstance(id)
       
  1639         for param, value in infos.items():
       
  1640             if param == "target":
       
  1641                 jump.setTargetName(value)
       
  1642             elif param == "height":
       
  1643                 jump.setHeight(value)
       
  1644             elif param == "width":
       
  1645                 jump.setWidth(value)
       
  1646             elif param == "x":
       
  1647                 jump.setX(value)
       
  1648             elif param == "y":
       
  1649                 jump.setY(value)
       
  1650             elif param == "connector":
       
  1651                 position = value.GetRelPosition()
       
  1652                 jump.addConnectionPointIn()
       
  1653                 jump.connectionPointIn.setRelPosition(position.x, position.y)
       
  1654                 self.SetConnectionWires(jump.connectionPointIn, value)
       
  1655  
       
  1656     def AddCurrentElementEditingActionBlock(self, id):
       
  1657         actionBlock = plcopen.actionBlock()
       
  1658         actionBlock.setLocalId(id)
       
  1659         self.GetCurrentElementEditing().addInstance("actionBlock", actionBlock)
       
  1660     
       
  1661     def SetCurrentElementEditingActionBlockInfos(self, id, infos):
       
  1662         actionBlock = self.GetCurrentElementEditing().getInstance(id)
       
  1663         for param, value in infos.items():
       
  1664             if param == "actions":
       
  1665                 actionBlock.setActions(value)
       
  1666             elif param == "height":
       
  1667                 actionBlock.setHeight(value)
       
  1668             elif param == "width":
       
  1669                 actionBlock.setWidth(value)
       
  1670             elif param == "x":
       
  1671                 actionBlock.setX(value)
       
  1672             elif param == "y":
       
  1673                 actionBlock.setY(value)
       
  1674             elif param == "connector":
       
  1675                 position = value.GetRelPosition()
       
  1676                 actionBlock.addConnectionPointIn()
       
  1677                 actionBlock.connectionPointIn.setRelPosition(position.x, position.y)
       
  1678                 self.SetConnectionWires(actionBlock.connectionPointIn, value)
       
  1679     
       
  1680     def RemoveCurrentElementEditingInstance(self, id):
       
  1681         self.GetCurrentElementEditing().removeInstance(id)
       
  1682         self.RefreshPouUsingTree()
       
  1683 
       
  1684     def GetCurrentResourceEditingVariables(self):
       
  1685         varlist = []
       
  1686         name = self.ElementsOpened[self.CurrentElementEditing]
       
  1687         words = name.split("::")
       
  1688         for var in self.GetConfigurationGlobalVars(words[1]):
       
  1689             if var["Type"] == "BOOL":
       
  1690                 varlist.append(var["Name"])
       
  1691         for var in self.GetConfigurationResourceGlobalVars(words[1], words[2]):
       
  1692             if var["Type"] == "BOOL":
       
  1693                 varlist.append(var["Name"])
       
  1694         return varlist
       
  1695 
       
  1696     def SetCurrentResourceEditingInfos(self, tasks, instances):
       
  1697         resource = self.GetCurrentElementEditing()
       
  1698         resource.setTask([])
       
  1699         resource.setPouInstance([])
       
  1700         task_list = {}
       
  1701         for task in tasks:
       
  1702             new_task = plcopen.resource_task()
       
  1703             new_task.setName(task["Name"])
       
  1704             if task["Single"] != "":
       
  1705                 new_task.setSingle(task["Single"])
       
  1706             if task["Interval"] != "":
       
  1707                 new_task.setInterval(task["Interval"])
       
  1708             new_task.priority.setValue(int(task["Priority"]))
       
  1709             if task["Name"] != "":
       
  1710                 task_list[task["Name"]] = new_task
       
  1711             resource.appendTask(new_task)
       
  1712         for instance in instances:
       
  1713             new_instance = plcopen.pouInstance()
       
  1714             new_instance.setName(instance["Name"])
       
  1715             new_instance.setType(instance["Type"])
       
  1716             if instance["Task"] != "":
       
  1717                 task_list[instance["Task"]].appendPouInstance(new_instance)
       
  1718             else:
       
  1719                 resource.appendPouInstance(new_instance)
       
  1720 
       
  1721     def GetCurrentResourceEditingInfos(self):
       
  1722         resource = self.GetCurrentElementEditing()
       
  1723         tasks = resource.getTask()
       
  1724         instances = resource.getPouInstance()
       
  1725         tasks_data = []
       
  1726         instances_data = []
       
  1727         for task in tasks:
       
  1728             new_task = {}
       
  1729             new_task["Name"] = task.getName()
       
  1730             single = task.getSingle()
       
  1731             if single:
       
  1732                 new_task["Single"] = single
       
  1733             else:
       
  1734                 new_task["Single"] = ""
       
  1735             interval = task.getInterval()
       
  1736             if interval:
       
  1737                 new_task["Interval"] = interval
       
  1738             else:
       
  1739                 new_task["Interval"] = ""
       
  1740             new_task["Priority"] = str(task.priority.getValue())
       
  1741             tasks_data.append(new_task)
       
  1742             for instance in task.getPouInstance():
       
  1743                 new_instance = {}
       
  1744                 new_instance["Name"] = instance.getName()
       
  1745                 new_instance["Type"] = instance.getType()
       
  1746                 new_instance["Task"] = task.getName()
       
  1747                 instances_data.append(new_instance)
       
  1748         for instance in instances:
       
  1749             new_instance = {}
       
  1750             new_instance["Name"] = instance.getName()
       
  1751             new_instance["Type"] = instance.getType()
       
  1752             new_instance["Task"] = ""
       
  1753             instances_data.append(new_instance)
       
  1754         return tasks_data, instances_data
       
  1755 
       
  1756     def OpenXMLFile(self, filepath):
       
  1757         if sys:
       
  1758             sys.stdout = plcopen.HolePseudoFile()
       
  1759         tree = pyxsval.parseAndValidate(filepath, "plcopen/TC6_XML_V10_B.xsd")
       
  1760         if sys:
       
  1761             sys.stdout = sys.__stdout__
       
  1762         
       
  1763         self.Project = plcopen.project()
       
  1764         self.Project.loadXMLTree(tree.getTree().childNodes[0])
       
  1765         self.UndoBuffer = UndoBuffer(self.Copy(self.Project), True)
       
  1766         self.SetFilePath(filepath)
       
  1767         self.ElementsOpened = []
       
  1768         self.CurrentElementEditing = None
       
  1769         self.RefreshPouUsingTree()
       
  1770         self.RefreshBlockTypes()
       
  1771 
       
  1772     def SaveXMLFile(self, filepath = None):
       
  1773         if not filepath and self.FilePath == "":
       
  1774             return False
       
  1775         else:
       
  1776             text = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
       
  1777             extras = {"xmlns" : "http://www.plcopen.org/xml/tc6.xsd",
       
  1778                       "xmlns:xhtml" : "http://www.w3.org/1999/xhtml",
       
  1779                       "xmlns:xsi" : "http://www.w3.org/2001/XMLSchema-instance",
       
  1780                       "xsi:schemaLocation" : "http://www.plcopen.org/xml/tc6.xsd http://www.plcopen.org/xml/tc6.xsd"}
       
  1781             text += self.Project.generateXMLText("project", 0, extras)
       
  1782 
       
  1783             if sys:
       
  1784                 sys.stdout = plcopen.HolePseudoFile()
       
  1785             pyxsval.parseAndValidateString(text, open("plcopen/TC6_XML_V10_B.xsd","r").read())
       
  1786             if sys:
       
  1787                 sys.stdout = sys.__stdout__
       
  1788             
       
  1789             if filepath:
       
  1790                 xmlfile = open(filepath,"w")
       
  1791             else:
       
  1792                 xmlfile = open(self.FilePath,"w")
       
  1793             xmlfile.write(text)
       
  1794             xmlfile.close()
       
  1795             self.UndoBuffer.CurrentSaved()
       
  1796             if filepath:
       
  1797                 self.SetFilePath(filepath)
       
  1798             return True
       
  1799 
       
  1800 #-------------------------------------------------------------------------------
       
  1801 #                      Current Buffering Management Functions
       
  1802 #-------------------------------------------------------------------------------
       
  1803 
       
  1804     """
       
  1805     Return a copy of the project
       
  1806     """
       
  1807     def Copy(self, model):
       
  1808         return cPickle.loads(cPickle.dumps(model))
       
  1809 
       
  1810     def BufferProject(self):
       
  1811         self.UndoBuffer.Buffering(self.Copy(self))
       
  1812 
       
  1813     def ProjectIsSaved(self):
       
  1814         return self.UndoBuffer.IsCurrentSaved()
       
  1815 
       
  1816     def LoadPrevious(self):
       
  1817         self.Project = self.Copy(self.UndoBuffer.Previous())
       
  1818         self.RefreshElementsOpened()
       
  1819     
       
  1820     def LoadNext(self):
       
  1821         self.Project = self.Copy(self.UndoBuffer.Next())
       
  1822         self.RefreshElementsOpened()
       
  1823     
       
  1824     def GetBufferState(self):
       
  1825         first = self.UndoBuffer.IsFirst()
       
  1826         last = self.UndoBuffer.IsLast()
       
  1827         return not first, not last