objdictgen/nodemanager.py
changeset 0 4472ee7c6c3e
child 30 a5dd050b28cb
equal deleted inserted replaced
-1:000000000000 0:4472ee7c6c3e
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 
       
     4 #This file is part of CanFestival, a library implementing CanOpen Stack. 
       
     5 #
       
     6 #Copyright (C): Edouard TISSERANT, Francis DUPIN and Laurent BESSARD
       
     7 #
       
     8 #See COPYING file for copyrights details.
       
     9 #
       
    10 #This library is free software; you can redistribute it and/or
       
    11 #modify it under the terms of the GNU Lesser General Public
       
    12 #License as published by the Free Software Foundation; either
       
    13 #version 2.1 of the License, or (at your option) any later version.
       
    14 #
       
    15 #This library is distributed in the hope that it will be useful,
       
    16 #but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    17 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    18 #Lesser General Public License for more details.
       
    19 #
       
    20 #You should have received a copy of the GNU Lesser General Public
       
    21 #License along with this library; if not, write to the Free Software
       
    22 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    23 
       
    24 from gnosis.xml.pickle import *
       
    25 from gnosis.xml.pickle.util import setParanoia
       
    26 setParanoia(0)
       
    27 
       
    28 from node import *
       
    29 import xml_in, gen_cfile
       
    30 
       
    31 from types import *
       
    32 import os, re
       
    33 
       
    34 UndoBufferLength = 20
       
    35 
       
    36 type_model = re.compile('([\_A-Z]*)([0-9]*)')
       
    37 range_model = re.compile('([\_A-Z]*)([0-9]*)\[([\-0-9]*)-([\-0-9]*)\]')
       
    38 name_model = re.compile('(.*)\[(.*)\]')
       
    39 
       
    40 def IsOfType(object, typedef):
       
    41     return type(object) == typedef
       
    42 
       
    43 #-------------------------------------------------------------------------------
       
    44 #                           Formating Name of an Entry
       
    45 #-------------------------------------------------------------------------------
       
    46 
       
    47 """
       
    48 Format the text given with the index and subindex defined
       
    49 """
       
    50 
       
    51 def StringFormat(text, idx, sub):
       
    52     result = name_model.match(text)
       
    53     if result:
       
    54         format = result.groups()
       
    55         return format[0]%eval(format[1])
       
    56     else:
       
    57         return text
       
    58 
       
    59 #-------------------------------------------------------------------------------
       
    60 #                         Search in a Mapping Dictionary
       
    61 #-------------------------------------------------------------------------------
       
    62 
       
    63 """
       
    64 Return the index of the informations in the Object Dictionary in case of identical
       
    65 indexes
       
    66 """
       
    67 def FindIndex(index, mappingdictionary):
       
    68     if index in mappingdictionary:
       
    69         return index
       
    70     else:
       
    71         listpluri = [idx for idx in mappingdictionary.keys() if mappingdictionary[idx]["struct"] & OD_IdenticalIndexes]
       
    72         listpluri.sort()
       
    73         for idx in listpluri:
       
    74             nb_max = mappingdictionary[idx]["nbmax"]
       
    75             incr = mappingdictionary[idx]["incr"]
       
    76             if idx < index < idx + incr * nb_max and (index - idx)%incr == 0:
       
    77                 return idx
       
    78     return None
       
    79 
       
    80 """
       
    81 Return the index of the typename given by searching in mappingdictionary 
       
    82 """
       
    83 def FindTypeIndex(typename, mappingdictionary):
       
    84     testdic = {}
       
    85     for index, values in mappingdictionary.iteritems():
       
    86         if index < 0x1000:
       
    87             testdic[values["name"]] = index
       
    88     if typename in testdic:
       
    89         return testdic[typename]
       
    90     return None
       
    91 
       
    92 """
       
    93 Return the name of the type by searching in mappingdictionary 
       
    94 """
       
    95 def FindTypeName(typeindex, mappingdictionary):
       
    96     if typeindex < 0x1000 and typeindex in mappingdictionary:
       
    97         return mappingdictionary[typeindex]["name"]
       
    98     return None
       
    99 
       
   100 """
       
   101 Return the default value of the type by searching in mappingdictionary 
       
   102 """
       
   103 def FindTypeDefaultValue(typeindex, mappingdictionary):
       
   104     if typeindex < 0x1000 and typeindex in mappingdictionary:
       
   105         return mappingdictionary[typeindex]["default"]
       
   106     return None
       
   107 
       
   108 """
       
   109 Return the list of types defined in mappingdictionary 
       
   110 """
       
   111 def FindTypeList(mappingdictionary):
       
   112     list = []
       
   113     for index in mappingdictionary.keys():
       
   114         if index < 0x1000:
       
   115             list.append((index, mappingdictionary[index]["name"]))
       
   116     return list
       
   117 
       
   118 """
       
   119 Return the name of an entry by searching in mappingdictionary 
       
   120 """
       
   121 def FindEntryName(index, mappingdictionary):
       
   122     base_index = FindIndex(index, mappingdictionary)
       
   123     if base_index:
       
   124         infos = mappingdictionary[base_index]
       
   125         if infos["struct"] & OD_IdenticalIndexes:
       
   126             return StringFormat(infos["name"], (index - base_index) / infos["incr"] + 1, 0)
       
   127         else:
       
   128             return infos["name"]
       
   129     return None
       
   130 
       
   131 """
       
   132 Return the informations of one entry by searching in mappingdictionary 
       
   133 """
       
   134 def FindEntryInfos(index, mappingdictionary):
       
   135     base_index = FindIndex(index, mappingdictionary)
       
   136     if base_index:
       
   137         copy = mappingdictionary[base_index].copy()
       
   138         if copy["struct"] & OD_IdenticalIndexes:
       
   139             copy["name"] = StringFormat(copy["name"], (index - base_index) / copy["incr"] + 1, 0)
       
   140         copy.pop("values")
       
   141         return copy
       
   142     return None
       
   143 
       
   144 """
       
   145 Return the informations of one subentry of an entry by searching in mappingdictionary 
       
   146 """
       
   147 def FindSubentryInfos(index, subIndex, mappingdictionary):
       
   148     base_index = FindIndex(index, mappingdictionary)
       
   149     if base_index:
       
   150         struct = mappingdictionary[base_index]["struct"]
       
   151         if struct & OD_Subindex:
       
   152             if struct & OD_IdenticalSubindexes:
       
   153                 if struct & OD_IdenticalIndexes:
       
   154                     incr = mappingdictionary[base_index]["incr"]
       
   155                 else:
       
   156                     incr = 1
       
   157                 if subIndex == 0:
       
   158                     return mappingdictionary[base_index]["values"][0].copy()
       
   159                 elif 0 < subIndex <= mappingdictionary[base_index]["values"][1]["nbmax"]:
       
   160                     copy = mappingdictionary[base_index]["values"][1].copy()
       
   161                     copy["name"] = StringFormat(copy["name"], (index - base_index) / incr + 1, subIndex)
       
   162                     return copy
       
   163             elif struct & OD_MultipleSubindexes and 0 <= subIndex < len(mappingdictionary[base_index]["values"]):
       
   164                 return mappingdictionary[base_index]["values"][subIndex].copy()
       
   165             elif subIndex == 0:
       
   166                 return mappingdictionary[base_index]["values"][0].copy()
       
   167     return None
       
   168 
       
   169 """
       
   170 Return the list of variables that can be mapped defined in mappingdictionary 
       
   171 """
       
   172 def FindMapVariableList(mappingdictionary, Manager):
       
   173     list = []
       
   174     for index in mappingdictionary.iterkeys():
       
   175         if Manager.IsCurrentEntry(index):
       
   176             for subIndex, values in enumerate(mappingdictionary[index]["values"]):
       
   177                 if mappingdictionary[index]["values"][subIndex]["pdo"]:
       
   178                     infos = Manager.GetEntryInfos(mappingdictionary[index]["values"][subIndex]["type"])
       
   179                     if mappingdictionary[index]["struct"] & OD_IdenticalSubindexes:
       
   180                         values = Manager.GetCurrentEntry(index)
       
   181                         for i in xrange(len(values)):
       
   182                             list.append((index, i + 1, infos["size"], StringFormat(mappingdictionary[index]["values"][subIndex]["name"],1,i)))
       
   183                     else:
       
   184                         list.append((index, subIndex, infos["size"], mappingdictionary[index]["values"][subIndex]["name"]))
       
   185     return list
       
   186 
       
   187 """
       
   188 Return the list of mandatory indexes defined in mappingdictionary 
       
   189 """
       
   190 def FindMandatoryIndexes(mappingdictionary):
       
   191     list = []
       
   192     for index in mappingdictionary.iterkeys():
       
   193         if index >= 0x1000 and mappingdictionary[index]["need"]:
       
   194             list.append(index)
       
   195     return list
       
   196 
       
   197 
       
   198 """
       
   199 Class implementing a buffer of changes made on the current editing Object Dictionary
       
   200 """
       
   201 
       
   202 class UndoBuffer:
       
   203 
       
   204     """
       
   205     Constructor initialising buffer
       
   206     """
       
   207     def __init__(self, currentstate, issaved = False):
       
   208         self.Buffer = []
       
   209         self.CurrentIndex = -1
       
   210         self.MinIndex = -1
       
   211         self.MaxIndex = -1
       
   212         # if current state is defined
       
   213         if currentstate:
       
   214             self.CurrentIndex = 0
       
   215             self.MinIndex = 0
       
   216             self.MaxIndex = 0
       
   217         # Initialising buffer with currentstate at the first place
       
   218         for i in xrange(UndoBufferLength):
       
   219             if i == 0:
       
   220                 self.Buffer.append(currentstate)
       
   221             else:
       
   222                 self.Buffer.append(None)
       
   223         # Initialising index of state saved
       
   224         if issaved:
       
   225             self.LastSave = 0
       
   226         else:
       
   227             self.LastSave = -1
       
   228     
       
   229     """
       
   230     Add a new state in buffer
       
   231     """
       
   232     def Buffering(self, currentstate):
       
   233         self.CurrentIndex = (self.CurrentIndex + 1) % UndoBufferLength
       
   234         self.Buffer[self.CurrentIndex] = currentstate
       
   235         # Actualising buffer limits
       
   236         self.MaxIndex = self.CurrentIndex
       
   237         if self.MinIndex == self.CurrentIndex:
       
   238             # If the removed state was the state saved, there is no state saved in the buffer
       
   239             if self.LastSave == self.MinIndex:
       
   240                 self.LastSave = -1
       
   241             self.MinIndex = (self.MinIndex + 1) % UndoBufferLength
       
   242         self.MinIndex = max(self.MinIndex, 0)
       
   243     
       
   244     """
       
   245     Return current state of buffer
       
   246     """
       
   247     def Current(self):
       
   248         return self.Buffer[self.CurrentIndex]
       
   249     
       
   250     """
       
   251     Change current state to previous in buffer and return new current state
       
   252     """
       
   253     def Previous(self):
       
   254         if self.CurrentIndex != self.MinIndex:
       
   255             self.CurrentIndex = (self.CurrentIndex - 1) % UndoBufferLength
       
   256             return self.Buffer[self.CurrentIndex]
       
   257         return None
       
   258     
       
   259     """
       
   260     Change current state to next in buffer and return new current state
       
   261     """
       
   262     def Next(self):
       
   263         if self.CurrentIndex != self.MaxIndex:
       
   264             self.CurrentIndex = (self.CurrentIndex + 1) % UndoBufferLength
       
   265             return self.Buffer[self.CurrentIndex]
       
   266         return None
       
   267     
       
   268     """
       
   269     Return True if current state is the first in buffer
       
   270     """
       
   271     def IsFirst(self):
       
   272         return self.CurrentIndex == self.MinIndex
       
   273     
       
   274     """
       
   275     Return True if current state is the last in buffer
       
   276     """
       
   277     def IsLast(self):
       
   278         return self.CurrentIndex == self.MaxIndex
       
   279 
       
   280     """
       
   281     Note that current state is saved
       
   282     """
       
   283     def CurrentSaved(self):
       
   284         self.LastSave = self.CurrentIndex
       
   285         
       
   286     """
       
   287     Return True if current state is saved
       
   288     """
       
   289     def IsCurrentSaved(self):
       
   290         return self.LastSave == self.CurrentIndex
       
   291 
       
   292 
       
   293 
       
   294 """
       
   295 Class which control the operations made on the node and answer to view requests
       
   296 """
       
   297 
       
   298 class NodeManager:
       
   299 
       
   300     """
       
   301     Constructor
       
   302     """
       
   303     def __init__(self):
       
   304         self.LastNewIndex = 0
       
   305         self.FilePaths = []
       
   306         self.FileNames = []
       
   307         self.NodeIndex = -1
       
   308         self.CurrentNode = None
       
   309         self.UndoBuffers = []
       
   310 
       
   311 #-------------------------------------------------------------------------------
       
   312 #                         Type and Map Variable Lists
       
   313 #-------------------------------------------------------------------------------
       
   314 
       
   315     """
       
   316     Generate the list of types defined for the current node
       
   317     """
       
   318     def GenerateTypeList(self):
       
   319         self.TypeList = ""
       
   320         self.TypeTranslation = {}
       
   321         list = self.GetTypeList()
       
   322         sep = ""
       
   323         for index, name in list:
       
   324             self.TypeList += "%s%s"%(sep,name)
       
   325             self.TypeTranslation[name] = index
       
   326             sep = ","
       
   327     
       
   328     """
       
   329     Generate the list of variables that can be mapped for the current node
       
   330     """
       
   331     def GenerateMapList(self):
       
   332         self.MapList = "None"
       
   333         self.NameTranslation = {"None" : "00000000"}
       
   334         self.MapTranslation = {"00000000" : "None"}
       
   335         list = self.GetMapVariableList()
       
   336         for index, subIndex, size, name in list:
       
   337             self.MapList += ",%s"%name
       
   338             map = "%04X%02X%02X"%(index,subIndex,size)
       
   339             self.NameTranslation[name] = map
       
   340             self.MapTranslation[map] = name
       
   341     
       
   342     """
       
   343     Return the list of types defined for the current node
       
   344     """
       
   345     def GetCurrentTypeList(self):
       
   346         return self.TypeList
       
   347 
       
   348     """
       
   349     Return the list of variables that can be mapped for the current node
       
   350     """
       
   351     def GetCurrentMapList(self):
       
   352         return self.MapList
       
   353 
       
   354 #-------------------------------------------------------------------------------
       
   355 #                        Create Load and Save Functions
       
   356 #-------------------------------------------------------------------------------
       
   357 
       
   358     """
       
   359     Create a new node and add a new buffer for storing it
       
   360     """
       
   361     def CreateNewNode(self, name, id, type, profile, filepath, NMT, options):
       
   362         # Create a new node
       
   363         node = Node()
       
   364         # Try to load profile given
       
   365         result = self.LoadProfile(profile, filepath, node)
       
   366         if not IsOfType(result, StringType):
       
   367             # if success, initialising node
       
   368             self.CurrentNode = node
       
   369             self.CurrentNode.SetNodeName(name)
       
   370             self.CurrentNode.SetNodeID(id)
       
   371             self.CurrentNode.SetNodeType(type)
       
   372             AddIndexList = self.GetMandatoryIndexes()
       
   373             if NMT == "NodeGuarding":
       
   374                 AddIndexList.extend([0x100C, 0x100D])
       
   375             elif NMT == "Heartbeat":
       
   376                 AddIndexList.append(0x1017)
       
   377             for option in options:
       
   378                 if option == "DS302":
       
   379                     # Charging DS-302 profile if choosen by user
       
   380                     if os.path.isfile("config/DS-302.prf"):
       
   381                         try:
       
   382                             Mapping = {}
       
   383                             AddMenuEntries = []
       
   384                             execfile("config/DS-302.prf")
       
   385                             self.CurrentNode.SetDS302Profile(Mapping)
       
   386                             self.CurrentNode.ExtendSpecificMenu(AddMenuEntries)
       
   387                         except:
       
   388                             return "Problem with DS-302! Syntax Error."
       
   389                     else:
       
   390                         return "Couldn't find DS-302 in 'config' folder!"
       
   391                 elif option == "GenSYNC":
       
   392                     AddIndexList.extend([0x1005, 0x1006])
       
   393                 elif option == "Emergency":
       
   394                     AddIndexList.append(0x1014)
       
   395                 elif option == "SaveConfig":
       
   396                     AddIndexList.extend([0x1010, 0x1011, 0x1020])
       
   397                 elif option == "StoreEDS":
       
   398                     AddIndexList.extend([0x1021, 0x1022])
       
   399             # Add a new buffer 
       
   400             self.AddNodeBuffer()
       
   401             self.SetCurrentFilePath("")
       
   402             # Add Mandatory indexes
       
   403             self.ManageEntriesOfCurrent(AddIndexList, [])
       
   404             # Regenerate lists
       
   405             self.GenerateTypeList()
       
   406             self.GenerateMapList()
       
   407             return True
       
   408         else:
       
   409             return result
       
   410     
       
   411     """
       
   412     Load a profile in node
       
   413     """
       
   414     def LoadProfile(self, profile, filepath, node):
       
   415         if profile != "None":
       
   416             # Try to charge the profile given
       
   417             try:
       
   418                 execfile(filepath)
       
   419                 node.SetProfileName(profile)
       
   420                 node.SetProfile(Mapping)
       
   421                 node.SetSpecificMenu(AddMenuEntries)
       
   422                 return True
       
   423             except:
       
   424                 return "Bad OD Profile file!\nSyntax Error."
       
   425         else:
       
   426             # Default profile
       
   427             node.SetProfileName("None")
       
   428             node.SetProfile({})
       
   429             node.SetSpecificMenu([])
       
   430             return True
       
   431 
       
   432     """
       
   433     Open a file and store it in a new buffer
       
   434     """
       
   435     def OpenFileInCurrent(self, filepath):
       
   436         # Open and load file
       
   437         file = open(filepath, "r")
       
   438         node = load(file)
       
   439         file.close()
       
   440         self.CurrentNode = node
       
   441         # Add a new buffer and defining current state
       
   442         self.AddNodeBuffer(self.CurrentNode.Copy(), True)
       
   443         self.SetCurrentFilePath(filepath)
       
   444         # Regenerate lists
       
   445         self.GenerateTypeList()
       
   446         self.GenerateMapList()
       
   447         return True
       
   448 
       
   449     """
       
   450     Save current node in  a file
       
   451     """
       
   452     def SaveCurrentInFile(self, filepath = None):
       
   453         # if no filepath given, verify if current node has a filepath defined
       
   454         if not filepath:
       
   455             filepath = self.GetCurrentFilePath()
       
   456             if filepath == "":
       
   457                 return False
       
   458         # Save node in file
       
   459         file = open(filepath, "w")
       
   460         dump(self.CurrentNode, file)
       
   461         file.close()
       
   462         self.SetCurrentFilePath(filepath)
       
   463         # Update saved state in buffer
       
   464         self.UndoBuffers[self.NodeIndex].CurrentSaved()
       
   465         return True
       
   466 
       
   467     """
       
   468     Close current state
       
   469     """
       
   470     def CloseCurrent(self, ignore = False):
       
   471         # Verify if it's not forced that the current node is saved before closing it
       
   472         if self.UndoBuffers[self.NodeIndex].IsCurrentSaved() or ignore:
       
   473             self.RemoveNodeBuffer(self.NodeIndex)
       
   474             return True
       
   475         return False
       
   476 
       
   477     """
       
   478     Import a xml file and store it in a new buffer if no node edited
       
   479     """
       
   480     def ImportCurrentFromFile(self, filepath):
       
   481         # Generate node from definition in a xml file
       
   482         node = xml_in.GenerateNode(filepath, self)
       
   483         if node:
       
   484             self.CurrentNode = node
       
   485             self.GenerateTypeList()
       
   486             self.GenerateMapList()
       
   487             if len(self.UndoBuffers) == 0:
       
   488                 self.AddNodeBuffer()
       
   489                 self.SetCurrentFilePath("")
       
   490             self.BufferCurrentNode()
       
   491         return result
       
   492     
       
   493     """
       
   494     Build the C definition of Object Dictionary for current node 
       
   495     """
       
   496     def ExportCurrentToFile(self, filepath):
       
   497         return gen_cfile.GenerateFile(filepath, self)
       
   498 
       
   499 #-------------------------------------------------------------------------------
       
   500 #                        Add Entries to Current Functions
       
   501 #-------------------------------------------------------------------------------
       
   502 
       
   503     """
       
   504     Add the specified number of subentry for the given entry. Verify that total
       
   505     number of subentry (except 0) doesn't exceed nbmax defined
       
   506     """
       
   507     def AddSubentriesToCurrent(self, index, number):
       
   508         # Informations about entry
       
   509         length = self.CurrentNode.GetEntry(index, 0)
       
   510         infos = self.GetEntryInfos(index)
       
   511         subentry_infos = self.GetSubentryInfos(index, 1)
       
   512         # Get default value for subindex
       
   513         if "default" in subentry_infos:
       
   514             default = subentry_infos["default"]
       
   515         else:
       
   516             default = self.GetTypeDefaultValue(subentry_infos["type"])   
       
   517         # First case entry is record
       
   518         if infos["struct"] & OD_IdenticalSubindexes:
       
   519             for i in xrange(1, min(number,subentry_infos["nbmax"]-length) + 1):
       
   520                 self.CurrentNode.AddEntry(index, length + i, default)
       
   521             self.BufferCurrentNode()
       
   522         # Second case entry is array, only possible for manufacturer specific
       
   523         elif infos["struct"] & OD_MultipleSubindexes and 0x2000 <= index <= 0x5FFF:
       
   524             values = {"name" : "Undefined", "type" : 5, "access" : "rw", "pdo" : True}
       
   525             for i in xrange(1, min(number,0xFE-length) + 1):
       
   526                 self.CurrentNode.AddMappingEntry(index, length + i, values = values.copy())
       
   527                 self.CurrentNode.AddEntry(index, length + i, 0)
       
   528             self.BufferCurrentNode()
       
   529 
       
   530     """
       
   531     Remove the specified number of subentry for the given entry. Verify that total
       
   532     number of subentry (except 0) isn't less than 1
       
   533     """
       
   534     def RemoveSubentriesFromCurrent(self, index, number):
       
   535         # Informations about entry
       
   536         infos = self.GetEntryInfos(index)
       
   537         length = self.CurrentNode.GetEntry(index, 0)
       
   538         # Entry is a record, or is an array of manufacturer specific
       
   539         if infos["struct"] & OD_IdenticalSubindexes or 0x2000 <= index <= 0x5FFF and infos["struct"] & OD_IdenticalSubindexes:
       
   540             for i in xrange(min(number, length - 1)):
       
   541                 self.RemoveCurrentVariable(index, length - i)
       
   542             self.BufferCurrentNode()
       
   543 
       
   544     """
       
   545     Add a SDO Server to current node
       
   546     """
       
   547     def AddSDOServerToCurrent(self):
       
   548         # An SDO Server is already defined at index 0x1200
       
   549         if self.CurrentNode.IsEntry(0x1200):
       
   550             indexlist = [self.GetLineFromIndex(0x1201)]
       
   551             if None not in indexlist:
       
   552                 self.ManageEntriesOfCurrent(indexlist, [])
       
   553         # Add an SDO Server at index 0x1200
       
   554         else:
       
   555             self.ManageEntriesOfCurrent([0x1200], [])
       
   556         
       
   557     """
       
   558     Add a SDO Server to current node
       
   559     """
       
   560     def AddSDOClientToCurrent(self):
       
   561         indexlist = [self.GetLineFromIndex(0x1280)]
       
   562         if None not in indexlist:
       
   563             self.ManageEntriesOfCurrent(indexlist, [])
       
   564 
       
   565     """
       
   566     Add a Transmit PDO to current node
       
   567     """
       
   568     def AddPDOTransmitToCurrent(self):
       
   569         indexlist = [self.GetLineFromIndex(0x1800),self.GetLineFromIndex(0x1A00)]
       
   570         if None not in indexlist:
       
   571             self.ManageEntriesOfCurrent(indexlist, [])
       
   572         
       
   573     """
       
   574     Add a Receive PDO to current node
       
   575     """
       
   576     def AddPDOReceiveToCurrent(self):
       
   577         indexlist = [self.GetLineFromIndex(0x1400),self.GetLineFromIndex(0x1600)]
       
   578         if None not in indexlist:
       
   579             self.ManageEntriesOfCurrent(indexlist, [])
       
   580 
       
   581     """
       
   582     Add a list of entries defined in profile for menu item selected to current node
       
   583     """
       
   584     def AddSpecificEntryToCurrent(self, menuitem):
       
   585         indexlist = []
       
   586         for menu, indexes in self.CurrentNode.GetSpecificMenu():
       
   587             if menuitem == menu:
       
   588                 for index in indexes:
       
   589                     indexlist.append(self.GetLineFromIndex(index))
       
   590         if None not in indexlist:
       
   591             self.ManageEntriesOfCurrent(indexlist, [])
       
   592 
       
   593     """
       
   594     Search the first index available for a pluri entry from base_index
       
   595     """
       
   596     def GetLineFromIndex(self, base_index):
       
   597         found = False
       
   598         index = base_index
       
   599         infos = self.GetEntryInfos(base_index)
       
   600         while index < base_index + infos["incr"]*infos["nbmax"] and not found:
       
   601             if not self.CurrentNode.IsEntry(index):
       
   602                 found = True
       
   603             else:
       
   604                 index += infos["incr"]
       
   605         if found:
       
   606             return index
       
   607         return None
       
   608     
       
   609     """
       
   610     Add entries specified in addinglist and remove entries specified in removinglist
       
   611     """
       
   612     def ManageEntriesOfCurrent(self, addinglist, removinglist):
       
   613         # Add all the entries in addinglist
       
   614         for index in addinglist:
       
   615             infos = self.GetEntryInfos(index)
       
   616             if infos["struct"] & OD_MultipleSubindexes:
       
   617                 # First case entry is a record
       
   618                 if infos["struct"] & OD_IdenticalSubindexes:
       
   619                     subentry_infos = self.GetSubentryInfos(index, 1)
       
   620                     if "default" in subentry_infos:
       
   621                         default = subentry_infos["default"]
       
   622                     else:
       
   623                         default = self.GetTypeDefaultValue(subentry_infos["type"])
       
   624                     self.CurrentNode.AddEntry(index, 1, default)
       
   625                 # Second case entry is a record
       
   626                 else:
       
   627                     i = 1
       
   628                     subentry_infos = self.GetSubentryInfos(index, i)
       
   629                     while subentry_infos:
       
   630                         if "default" in subentry_infos:
       
   631                             default = subentry_infos["default"]
       
   632                         else:
       
   633                             default = self.GetTypeDefaultValue(subentry_infos["type"])
       
   634                         self.CurrentNode.AddEntry(index, i, default)
       
   635                         i += 1
       
   636                         subentry_infos = self.GetSubentryInfos(index, i)
       
   637             # Third case entry is a record
       
   638             else:
       
   639                 subentry_infos = self.GetSubentryInfos(index, 0)
       
   640                 if "default" in subentry_infos:
       
   641                     default = subentry_infos["default"]
       
   642                 else:
       
   643                     default = self.GetTypeDefaultValue(subentry_infos["type"])
       
   644                 self.CurrentNode.AddEntry(index, 0, default)
       
   645         # Remove all the entries in removinglist
       
   646         for index in removinglist:
       
   647             self.RemoveCurrentVariable(index)
       
   648         self.BufferCurrentNode()
       
   649 
       
   650     """
       
   651     Remove an entry from current node. Analize the index to perform the correct
       
   652     method
       
   653     """
       
   654     def RemoveCurrentVariable(self, index, subIndex = None):
       
   655         Mappings = self.CurrentNode.GetMappings()
       
   656         if index < 0x1000 and subIndex == None:
       
   657             type = self.CurrentNode.GetEntry(index, 1)
       
   658             for i in Mappings[-1]:
       
   659                 for value in Mappings[-1][i]["values"]:
       
   660                     if value["type"] == index:
       
   661                         value["type"] = type
       
   662             self.CurrentNode.RemoveMappingEntry(index)
       
   663             self.CurrentNode.RemoveEntry(index)
       
   664         elif index == 0x1200 and subIndex == None:
       
   665             self.CurrentNode.RemoveEntry(0x1200)
       
   666         elif 0x1201 <= index <= 0x127F and subIndex == None:
       
   667             self.CurrentNode.RemoveLine(index, 0x127F)
       
   668         elif 0x1280 <= index <= 0x12FF and subIndex == None:
       
   669             self.CurrentNode.RemoveLine(index, 0x12FF)
       
   670         elif 0x1400 <= index <= 0x15FF or 0x1600 <= index <= 0x17FF and subIndex == None:
       
   671             if 0x1600 <= index <= 0x17FF and subIndex == None:
       
   672                 index -= 0x200
       
   673             self.CurrentNode.RemoveLine(index, 0x15FF)
       
   674             self.CurrentNode.RemoveLine(index + 0x200, 0x17FF)
       
   675         elif 0x1800 <= index <= 0x19FF or 0x1A00 <= index <= 0x1BFF and subIndex == None:
       
   676             if 0x1A00 <= index <= 0x1BFF:
       
   677                 index -= 0x200
       
   678             self.CurrentNode.RemoveLine(index, 0x19FF)
       
   679             self.CurrentNode.RemoveLine(index + 0x200, 0x1BFF)
       
   680         else:
       
   681             found = False
       
   682             for menu,list in self.CurrentNode.GetSpecificMenu():
       
   683                 for i in list:
       
   684                     iinfos = self.GetEntryInfos(i)
       
   685                     indexes = [i + incr * iinfos["incr"] for incr in xrange(iinfos["nbmax"])] 
       
   686                     if index in indexes:
       
   687                         found = True
       
   688                         diff = index - i
       
   689                         for j in list:
       
   690                             jinfos = self.GetEntryInfos(j)
       
   691                             self.CurrentNode.RemoveLine(j + diff, j + jinfos["incr"]*jinfos["nbmax"], jinfos["incr"])
       
   692             self.CurrentNode.RemoveMapVariable(index, subIndex)
       
   693             if not found:
       
   694                 infos = self.GetEntryInfos(index)
       
   695                 if not infos["need"]:
       
   696                     self.CurrentNode.RemoveEntry(index, subIndex)
       
   697             if index in Mappings[-1]:
       
   698                 self.CurrentNode.RemoveMappingEntry(index, subIndex)
       
   699             self.GenerateMapList()
       
   700 
       
   701     def AddMapVariableToCurrent(self, index, name, struct, number):
       
   702         if 0x2000 <= index <= 0x5FFF:
       
   703             if not self.CurrentNode.IsEntry(index):
       
   704                 self.CurrentNode.AddMappingEntry(index, name = name, struct = struct)
       
   705                 if struct == var:
       
   706                     values = {"name" : name, "type" : 5, "access" : "rw", "pdo" : True}
       
   707                     self.CurrentNode.AddMappingEntry(index, 0, values = values)
       
   708                     self.CurrentNode.AddEntry(index, 0, 0)
       
   709                 else:
       
   710                     values = {"name" : "Number of Entries", "type" : 2, "access" : "ro", "pdo" : False}
       
   711                     self.CurrentNode.AddMappingEntry(index, 0, values = values)
       
   712                     if struct == rec:
       
   713                         values = {"name" : name + " %d[(sub)]", "type" : 5, "access" : "rw", "pdo" : True, "nbmax" : 0xFE}
       
   714                         self.CurrentNode.AddMappingEntry(index, 1, values = values)
       
   715                         for i in xrange(number):
       
   716                             self.CurrentNode.AddEntry(index, i + 1, 0)
       
   717                     else:
       
   718                         for i in xrange(number):
       
   719                             values = {"name" : "Undefined", "type" : 5, "access" : "rw", "pdo" : True}
       
   720                             self.CurrentNode.AddMappingEntry(index, i + 1, values = values)
       
   721                             self.CurrentNode.AddEntry(index, i + 1, 0)
       
   722                 self.GenerateMapList()
       
   723                 self.BufferCurrentNode()
       
   724                 return None
       
   725             else:
       
   726                 return "Index 0x%04X already defined!"%index
       
   727         else:
       
   728             return "Index 0x%04X isn't a valid index for Map Variable!"%index
       
   729 
       
   730     def AddUserTypeToCurrent(self, type, min, max, length):
       
   731         index = 0xA0
       
   732         while index < 0x100 and self.CurrentNode.IsEntry(index):
       
   733             index += 1
       
   734         if index < 0x100:
       
   735             customisabletypes = self.GetCustomisableTypes()
       
   736             name, valuetype = customisabletypes[type]
       
   737             size = self.GetEntryInfos(type)["size"]
       
   738             default = self.GetTypeDefaultValue(type)
       
   739             if valuetype == 0:
       
   740                 self.CurrentNode.AddMappingEntry(index, name = "%s[%d-%d]"%(name, min, max), struct = 3, size = size, default = default)
       
   741                 self.CurrentNode.AddMappingEntry(index, 0, values = {"name" : "Number of Entries", "type" : 0x02, "access" : "ro", "pdo" : False})
       
   742                 self.CurrentNode.AddMappingEntry(index, 1, values = {"name" : "Type", "type" : 0x02, "access" : "ro", "pdo" : False})
       
   743                 self.CurrentNode.AddMappingEntry(index, 2, values = {"name" : "Minimum Value", "type" : type, "access" : "ro", "pdo" : False})
       
   744                 self.CurrentNode.AddMappingEntry(index, 3, values = {"name" : "Maximum Value", "type" : type, "access" : "ro", "pdo" : False})
       
   745                 self.CurrentNode.AddEntry(index, 1, type)
       
   746                 self.CurrentNode.AddEntry(index, 2, min)
       
   747                 self.CurrentNode.AddEntry(index, 3, max)
       
   748             elif valuetype == 1:
       
   749                 self.CurrentNode.AddMappingEntry(index, name = "%s%d"%(name, length), struct = 3, size = length * size, default = default)
       
   750                 self.CurrentNode.AddMappingEntry(index, 0, values = {"name" : "Number of Entries", "type" : 0x02, "access" : "ro", "pdo" : False})
       
   751                 self.CurrentNode.AddMappingEntry(index, 1, values = {"name" : "Type", "type" : 0x02, "access" : "ro", "pdo" : False})
       
   752                 self.CurrentNode.AddMappingEntry(index, 2, values = {"name" : "Length", "type" : 0x02, "access" : "ro", "pdo" : False})
       
   753                 self.CurrentNode.AddEntry(index, 1, type)
       
   754                 self.CurrentNode.AddEntry(index, 2, length)
       
   755             self.GenerateTypeList()
       
   756             self.BufferCurrentNode()
       
   757             return None
       
   758         else:
       
   759             return "Too many User Types have already been defined!"
       
   760 
       
   761 #-------------------------------------------------------------------------------
       
   762 #                      Modify Entry and Mapping Functions
       
   763 #-------------------------------------------------------------------------------
       
   764 
       
   765     def SetCurrentEntryCallbacks(self, index, value):
       
   766         if self.CurrentNode and self.CurrentNode.IsEntry(index):
       
   767             entry_infos = self.GetEntryInfos(index)
       
   768             if "callback" not in entry_infos:
       
   769                 self.CurrentNode.SetParamsEntry(index, None, callback = value)
       
   770                 self.BufferCurrentNode()
       
   771 
       
   772     def SetCurrentEntry(self, index, subIndex, value, name, editor):
       
   773         if self.CurrentNode and self.CurrentNode.IsEntry(index):
       
   774             if name == "value":
       
   775                 if editor == "map":
       
   776                     value = eval("0x%s"%self.NameTranslation[value])
       
   777                     self.CurrentNode.SetEntry(index, subIndex, value)
       
   778                 elif editor == "bool":
       
   779                     value = value == "True"
       
   780                     self.CurrentNode.SetEntry(index, subIndex, value)
       
   781                 else:
       
   782                     subentry_infos = self.GetSubentryInfos(index, subIndex)
       
   783                     dic = {}
       
   784                     for typeindex, typevalue in CustomisableTypes:
       
   785                         dic[typeindex] = typevalue
       
   786                     if dic[subentry_infos["type"]] == 0:
       
   787                         try:
       
   788                             value = eval(value, {})
       
   789                             self.CurrentNode.SetEntry(index, subIndex, value)
       
   790                         except:
       
   791                             pass
       
   792                     else:
       
   793                         self.CurrentNode.SetEntry(index, subIndex, value)
       
   794             elif name in ["comment", "save"]:
       
   795                 if editor == "option":
       
   796                     value = value == "Yes"
       
   797                 if name == "save":
       
   798                     self.CurrentNode.SetParamsEntry(index, subIndex, save = value)
       
   799                 elif name == "comment":
       
   800                     self.CurrentNode.SetParamsEntry(index, subIndex, comment = value)
       
   801             else:
       
   802                 if editor == "type":
       
   803                     value = self.TypeTranslation[value]
       
   804                 elif editor == "access":
       
   805                     dic = {}
       
   806                     for abbrev,access in AccessType.iteritems():
       
   807                         dic[access] = abbrev
       
   808                     value = dic[value]
       
   809                 self.CurrentNode.SetMappingEntry(index, subIndex, values = {name : value})
       
   810                 if name == "name":
       
   811                     self.GenerateMapList()
       
   812             self.BufferCurrentNode()
       
   813 
       
   814     def SetCurrentEntryName(self, index, name):
       
   815         self.CurrentNode.SetMappingEntry(index, name=name)
       
   816         self.BufferCurrentNode()
       
   817 
       
   818     def SetCurrentUserType(self, index, type, min, max, length):
       
   819         customisabletypes = self.GetCustomisableTypes()
       
   820         values, valuetype = self.GetCustomisedTypeValues(index)
       
   821         name, new_valuetype = customisabletypes[type]
       
   822         size = self.GetEntryInfos(type)["size"]
       
   823         default = self.GetTypeDefaultValue(type)
       
   824         if new_valuetype == 0:
       
   825             self.CurrentNode.SetMappingEntry(index, name = "%s[%d-%d]"%(name, min, max), struct = 3, size = size, default = default) 
       
   826             if valuetype == 1:
       
   827                 self.CurrentNode.SetMappingEntry(index, 2, values = {"name" : "Minimum Value", "type" : type, "access" : "ro", "pdo" : False})
       
   828                 self.CurrentNode.AddMappingEntry(index, 3, values = {"name" : "Maximum Value", "type" : type, "access" : "ro", "pdo" : False})
       
   829             self.CurrentNode.SetEntry(index, 1, type)
       
   830             self.CurrentNode.SetEntry(index, 2, min)
       
   831             if valuetype == 1:
       
   832                 self.CurrentNode.AddEntry(index, 3, max)
       
   833             else:
       
   834                 self.CurrentNode.SetEntry(index, 3, max)
       
   835         elif new_valuetype == 1:
       
   836             self.CurrentNode.SetMappingEntry(index, name = "%s%d"%(name, length), struct = 3, size = size, default = default)
       
   837             if valuetype == 0:
       
   838                 self.CurrentNode.SetMappingEntry(index, 2, values = {"name" : "Length", "type" : 0x02, "access" : "ro", "pdo" : False})
       
   839                 self.CurrentNode.RemoveMappingEntry(index, 3)
       
   840             self.CurrentNode.SetEntry(index, 1, type)
       
   841             self.CurrentNode.SetEntry(index, 2, length)
       
   842             if valuetype == 0:
       
   843                 self.CurrentNode.RemoveEntry(index, 3)
       
   844         self.BufferCurrentNode()
       
   845 
       
   846 #-------------------------------------------------------------------------------
       
   847 #                      Current Buffering Management Functions
       
   848 #-------------------------------------------------------------------------------
       
   849 
       
   850     def BufferCurrentNode(self):
       
   851         self.UndoBuffers[self.NodeIndex].Buffering(self.CurrentNode.Copy())
       
   852 
       
   853     def CurrentIsSaved(self):
       
   854         return self.UndoBuffers[self.NodeIndex].IsCurrentSaved()
       
   855 
       
   856     def OneFileHasChanged(self):
       
   857         result = False
       
   858         for buffer in self.UndoBuffers:
       
   859             result |= not buffer.IsCurrentSaved()
       
   860         return result
       
   861 
       
   862     def GetBufferNumber(self):
       
   863         return len(self.UndoBuffers)
       
   864 
       
   865     def LoadCurrentPrevious(self):
       
   866         self.CurrentNode = self.UndoBuffers[self.NodeIndex].Previous().Copy()
       
   867     
       
   868     def LoadCurrentNext(self):
       
   869         self.CurrentNode = self.UndoBuffers[self.NodeIndex].Next().Copy()
       
   870 
       
   871     def AddNodeBuffer(self, currentstate = None, issaved = False):
       
   872         self.NodeIndex = len(self.UndoBuffers)
       
   873         self.UndoBuffers.append(UndoBuffer(currentstate, issaved))
       
   874         self.FilePaths.append("")
       
   875         self.FileNames.append("")
       
   876 
       
   877     def ChangeCurrentNode(self, index):
       
   878         if index < len(self.UndoBuffers):
       
   879             self.NodeIndex = index
       
   880             self.CurrentNode = self.UndoBuffers[self.NodeIndex].Current().Copy()
       
   881             self.GenerateTypeList()
       
   882             self.GenerateMapList()
       
   883     
       
   884     def RemoveNodeBuffer(self, index):
       
   885         self.UndoBuffers.pop(index)
       
   886         self.FilePaths.pop(index)
       
   887         self.FileNames.pop(index)
       
   888         self.NodeIndex = min(self.NodeIndex, len(self.UndoBuffers) - 1)
       
   889         if len(self.UndoBuffers) > 0:
       
   890             self.CurrentNode = self.UndoBuffers[self.NodeIndex].Current().Copy()
       
   891             self.GenerateTypeList()
       
   892             self.GenerateMapList()
       
   893         else:
       
   894             self.CurrentNode = None
       
   895     
       
   896     def GetCurrentNodeIndex(self):
       
   897         return self.NodeIndex
       
   898     
       
   899     def GetCurrentFilename(self):
       
   900         return self.GetFilename(self.NodeIndex)
       
   901     
       
   902     def GetAllFilenames(self):
       
   903         filenames = []
       
   904         for i in xrange(len(self.UndoBuffers)):
       
   905             filenames.append(self.GetFilename(i))
       
   906         return filenames
       
   907     
       
   908     def GetFilename(self, index):
       
   909         if self.UndoBuffers[index].IsCurrentSaved():
       
   910             return self.FileNames[index]
       
   911         else:
       
   912             return "~%s~"%self.FileNames[index]
       
   913     
       
   914     def SetCurrentFilePath(self, filepath):
       
   915         self.FilePaths[self.NodeIndex] = filepath
       
   916         if filepath == "":
       
   917             self.LastNewIndex += 1
       
   918             self.FileNames[self.NodeIndex] = "Unnamed%d"%self.LastNewIndex
       
   919         else:
       
   920             self.FileNames[self.NodeIndex] = os.path.splitext(os.path.basename(filepath))[0]
       
   921                 
       
   922     def GetCurrentFilePath(self):
       
   923         if len(self.FilePaths) > 0:
       
   924             return self.FilePaths[self.NodeIndex]
       
   925         else:
       
   926             return ""
       
   927     
       
   928     def GetCurrentBufferState(self):
       
   929         first = self.UndoBuffers[self.NodeIndex].IsFirst()
       
   930         last = self.UndoBuffers[self.NodeIndex].IsLast()
       
   931         return not first, not last
       
   932 
       
   933 #-------------------------------------------------------------------------------
       
   934 #                         Profiles Management Functions
       
   935 #-------------------------------------------------------------------------------
       
   936 
       
   937     def GetCurrentCommunicationLists(self):
       
   938         list = []
       
   939         for index in MappingDictionary.iterkeys():
       
   940             if 0x1000 <= index < 0x1200:
       
   941                 list.append(index)
       
   942         return self.GetProfileLists(MappingDictionary, list)
       
   943     
       
   944     def GetCurrentDS302Lists(self):
       
   945         return self.GetSpecificProfileLists(self.CurrentNode.GetDS302Profile())
       
   946     
       
   947     def GetCurrentProfileLists(self):
       
   948         return self.GetSpecificProfileLists(self.CurrentNode.GetProfile())
       
   949     
       
   950     def GetSpecificProfileLists(self, mappingdictionary):
       
   951         validlist = []
       
   952         exclusionlist = []
       
   953         for name, list in self.CurrentNode.GetSpecificMenu():
       
   954             exclusionlist.extend(list)
       
   955         for index in mappingdictionary.iterkeys():
       
   956             if index not in exclusionlist:
       
   957                 validlist.append(index)
       
   958         return self.GetProfileLists(mappingdictionary, validlist)
       
   959     
       
   960     def GetProfileLists(self, mappingdictionary, list):
       
   961         dictionary = {}
       
   962         current = []
       
   963         for index in list:
       
   964             dictionary[index] = (mappingdictionary[index]["name"], mappingdictionary[index]["need"])
       
   965             if self.CurrentNode.IsEntry(index):
       
   966                 current.append(index)
       
   967         return dictionary, current
       
   968 
       
   969     def CurrentDS302Defined(self):
       
   970         if self.CurrentNode:
       
   971             return len(self.CurrentNode.GetDS302Profile()) > 0
       
   972         return False
       
   973 
       
   974 #-------------------------------------------------------------------------------
       
   975 #                         Node State and Values Functions
       
   976 #-------------------------------------------------------------------------------
       
   977 
       
   978     def GetCurrentNodeInfos(self):
       
   979         name = self.CurrentNode.GetNodeName()
       
   980         id = self.CurrentNode.GetNodeID()
       
   981         type = self.CurrentNode.GetNodeType()
       
   982         return name, id, type
       
   983         
       
   984     def SetCurrentNodeInfos(self, name, id, type):
       
   985         self.CurrentNode.SetNodeName(name)
       
   986         self.CurrentNode.SetNodeID(id)
       
   987         self.CurrentNode.SetNodeType(type)
       
   988         self.BufferCurrentNode()
       
   989 
       
   990     def GetCurrentProfileName(self):
       
   991         if self.CurrentNode:
       
   992             return self.CurrentNode.GetProfileName()
       
   993         return ""
       
   994 
       
   995     def IsCurrentEntry(self, index):
       
   996         if self.CurrentNode:
       
   997             return self.CurrentNode.IsEntry(index)
       
   998         return False
       
   999     
       
  1000     def GetCurrentEntry(self, index, subIndex = None):
       
  1001         if self.CurrentNode:
       
  1002             return self.CurrentNode.GetEntry(index, subIndex)
       
  1003         return None
       
  1004     
       
  1005     def GetCurrentParamsEntry(self, index, subIndex = None):
       
  1006         if self.CurrentNode:
       
  1007             return self.CurrentNode.GetParamsEntry(index, subIndex)
       
  1008         return None
       
  1009     
       
  1010     def GetCurrentValidIndexes(self, min, max):
       
  1011         validindexes = []
       
  1012         for index in self.CurrentNode.GetIndexes():
       
  1013             if min <= index <= max:
       
  1014                 validindexes.append((self.GetEntryName(index), index))
       
  1015         return validindexes
       
  1016         
       
  1017     def GetCurrentValidChoices(self, min, max):
       
  1018         validchoices = []
       
  1019         exclusionlist = []
       
  1020         for menu, indexes in self.CurrentNode.GetSpecificMenu():
       
  1021             exclusionlist.extend(indexes)
       
  1022             good = True
       
  1023             for index in indexes:
       
  1024                 good &= min <= index <= max
       
  1025             if good:
       
  1026                 validchoices.append((menu, None))
       
  1027         list = [index for index in MappingDictionary.keys() if index >= 0x1000]
       
  1028         profiles = self.CurrentNode.GetMappings(False)
       
  1029         for profile in profiles:
       
  1030             list.extend(profile.keys())
       
  1031         list.sort()
       
  1032         for index in list:
       
  1033             if min <= index <= max and not self.CurrentNode.IsEntry(index) and index not in exclusionlist:
       
  1034                 validchoices.append((self.GetEntryName(index), index))
       
  1035         return validchoices
       
  1036     
       
  1037     def HasCurrentEntryCallbacks(self, index):
       
  1038         if self.CurrentNode and self.CurrentNode.IsEntry(index):
       
  1039             entry_infos = self.GetEntryInfos(index)
       
  1040             if "callback" in entry_infos:
       
  1041                 return entry_infos["callback"]
       
  1042             return self.CurrentNode.HasEntryCallbacks(index)
       
  1043         return False
       
  1044     
       
  1045     def GetCurrentEntryValues(self, index):
       
  1046         if self.CurrentNode and self.CurrentNode.IsEntry(index):
       
  1047             entry_infos = self.GetEntryInfos(index)
       
  1048             data = []
       
  1049             editors = []
       
  1050             values = self.CurrentNode.GetEntry(index)
       
  1051             params = self.CurrentNode.GetParamsEntry(index)
       
  1052             if type(values) == ListType:
       
  1053                 for i, value in enumerate(values):
       
  1054                     data.append({"value" : value})
       
  1055                     data[-1].update(params[i])
       
  1056             else:
       
  1057                 data.append({"value" : values})
       
  1058                 data[-1].update(params)
       
  1059             for i, dic in enumerate(data):
       
  1060                 infos = self.GetSubentryInfos(index, i)
       
  1061                 dic["subindex"] = "0x%02X"%i
       
  1062                 dic["name"] = infos["name"]
       
  1063                 dic["type"] = self.GetTypeName(infos["type"])
       
  1064                 dic["access"] = AccessType[infos["access"]]
       
  1065                 dic["save"] = OptionType[dic["save"]]
       
  1066                 editor = {"subindex" : None, "save" : "option", "callback" : "option", "comment" : "string"}
       
  1067                 if type(values) == ListType and i == 0:
       
  1068                     editor["name"] = None
       
  1069                     editor["type"] = None
       
  1070                     editor["access"] = None
       
  1071                     editor["value"] = None
       
  1072                 else:
       
  1073                     if infos["user_defined"]:
       
  1074                         if entry_infos["struct"] & OD_IdenticalSubindexes:
       
  1075                             editor["name"] = None
       
  1076                             if i > 1:
       
  1077                                 editor["type"] = None
       
  1078                                 editor["access"] = None
       
  1079                             else:
       
  1080                                 editor["type"] = "type"
       
  1081                                 editor["access"] = "access"
       
  1082                         else:
       
  1083                             if entry_infos["struct"] & OD_MultipleSubindexes:
       
  1084                                 editor["name"] = "string"
       
  1085                             else:
       
  1086                                 editor["name"] = None
       
  1087                             editor["type"] = "type"
       
  1088                             editor["access"] = "access"
       
  1089                     else:
       
  1090                         editor["name"] = None
       
  1091                         editor["type"] = None
       
  1092                         editor["access"] = None
       
  1093                     if index < 0x260:
       
  1094                         editor["value"] = None
       
  1095                         if i == 1:
       
  1096                             dic["value"] = self.GetTypeName(dic["value"])
       
  1097                     elif 0x1600 <= index <= 0x17FF or 0x1A00 <= index <= 0x1C00:
       
  1098                         editor["value"] = "map"
       
  1099                         dic["value"] = self.MapTranslation["%08X"%dic["value"]]
       
  1100                     else:
       
  1101                         if dic["type"].startswith("VISIBLE_STRING"):
       
  1102                             editor["value"] = "string"
       
  1103                         elif dic["type"] == "BOOLEAN":
       
  1104                             editor["value"] = "bool"
       
  1105                             dic["value"] = BoolType[dic["value"]]
       
  1106                         result = type_model.match(dic["type"])
       
  1107                         if result:
       
  1108                             values = result.groups()
       
  1109                             if values[0] == "INTEGER":
       
  1110                                 format = "0x%0" + str(int(values[1])/4) + "X"
       
  1111                                 dic["value"] = format%dic["value"]
       
  1112                                 editor["value"] = "string"
       
  1113                             elif values[0] == "UNSIGNED":
       
  1114                                 editor["value"] = "number"
       
  1115                             elif values[0] == "REAL":
       
  1116                                 editor["value"] = "float"
       
  1117                             elif values[0] == "VISIBLE_STRING":
       
  1118                                 editor["length"] = values[0]
       
  1119                         result = range_model.match(dic["type"])
       
  1120                         if result:
       
  1121                             values = result.groups()
       
  1122                             if values[0] in ("UNSIGNED", "REAL"):
       
  1123                                 editor["min"] = values[2]
       
  1124                                 editor["max"] = values[3]
       
  1125                 editors.append(editor)
       
  1126             return data, editors
       
  1127         else:
       
  1128             return None
       
  1129     
       
  1130 #-------------------------------------------------------------------------------
       
  1131 #                         Node Informations Functions
       
  1132 #-------------------------------------------------------------------------------
       
  1133 
       
  1134     def GetCustomisedTypeValues(self, index):
       
  1135         values = self.CurrentNode.GetEntry(index)
       
  1136         customisabletypes = self.GetCustomisableTypes()
       
  1137         return values, customisabletypes[values[1]][1]
       
  1138 
       
  1139     def GetEntryName(self, index, node = True):
       
  1140         result = FindEntryName(index, MappingDictionary)
       
  1141         if result == None and node:
       
  1142             NodeMappings = self.CurrentNode.GetMappings()
       
  1143             i = 0
       
  1144             while not result and i < len(NodeMappings):
       
  1145                 result = FindEntryName(index, NodeMappings[i])
       
  1146                 i += 1
       
  1147         return result
       
  1148     
       
  1149     def GetEntryInfos(self, index, node = True):
       
  1150         result = FindEntryInfos(index, MappingDictionary)
       
  1151         if result == None and node:
       
  1152             NodeMappings = self.CurrentNode.GetMappings()
       
  1153             i = 0
       
  1154             while not result and i < len(NodeMappings):
       
  1155                 result = FindEntryInfos(index, NodeMappings[i])
       
  1156                 i += 1
       
  1157         return result
       
  1158     
       
  1159     def GetSubentryInfos(self, index, subIndex, node = True):
       
  1160         result = FindSubentryInfos(index, subIndex, MappingDictionary)
       
  1161         if result == None and node:
       
  1162             NodeMappings = self.CurrentNode.GetMappings()
       
  1163             i = 0
       
  1164             while not result and i < len(NodeMappings):
       
  1165                 result = FindSubentryInfos(index, subIndex, NodeMappings[i])
       
  1166                 if result:
       
  1167                     result["user_defined"] = i == len(NodeMappings) - 1 and index >= 0x1000
       
  1168                 i += 1
       
  1169         else :
       
  1170             result["user_defined"] = False
       
  1171         return result
       
  1172     
       
  1173     def GetTypeIndex(self, typename, node = True):
       
  1174         result = FindTypeIndex(typename, MappingDictionary)
       
  1175         if result == None and node:
       
  1176             NodeMappings = self.CurrentNode.GetMappings()
       
  1177             i = 0
       
  1178             while not result and i < len(NodeMappings):
       
  1179                 result = FindTypeIndex(typename, NodeMappings[i])
       
  1180                 i += 1
       
  1181         return result
       
  1182     
       
  1183     def GetTypeName(self, typeindex, node = True):
       
  1184         result = FindTypeName(typeindex, MappingDictionary)
       
  1185         if result == None and node:
       
  1186             NodeMappings = self.CurrentNode.GetMappings()
       
  1187             i = 0
       
  1188             while not result and i < len(NodeMappings):
       
  1189                 result = FindTypeName(typeindex, NodeMappings[i])
       
  1190                 i += 1
       
  1191         return result
       
  1192     
       
  1193     def GetTypeDefaultValue(self, typeindex, node = True):
       
  1194         result = FindTypeDefaultValue(typeindex, MappingDictionary)
       
  1195         if result == None and node:
       
  1196             NodeMappings = self.CurrentNode.GetMappings()
       
  1197             i = 0
       
  1198             while not result and i < len(NodeMappings):
       
  1199                 result = FindTypeDefaultValue(typeindex, NodeMappings[i])
       
  1200                 i += 1
       
  1201         return result
       
  1202     
       
  1203     def GetTypeList(self, node = True):
       
  1204         list = FindTypeList(MappingDictionary)
       
  1205         if node:
       
  1206             for NodeMapping in self.CurrentNode.GetMappings():
       
  1207                 list.extend(FindTypeList(NodeMapping))
       
  1208         list.sort()
       
  1209         return list
       
  1210     
       
  1211     def GetMapVariableList(self):
       
  1212         list = FindMapVariableList(MappingDictionary, self)
       
  1213         for NodeMapping in self.CurrentNode.GetMappings():
       
  1214             list.extend(FindMapVariableList(NodeMapping, self))
       
  1215         list.sort()
       
  1216         return list
       
  1217     
       
  1218     def GetMandatoryIndexes(self, node = True):
       
  1219         list = FindMandatoryIndexes(MappingDictionary)
       
  1220         if node:
       
  1221             for NodeMapping in self.CurrentNode.GetMappings():
       
  1222                 list.extend(FindMandatoryIndexes(NodeMapping))
       
  1223         return list
       
  1224     
       
  1225     def GetCustomisableTypes(self):
       
  1226         dic = {}
       
  1227         for index, valuetype in CustomisableTypes:
       
  1228             name = self.GetTypeName(index)
       
  1229             dic[index] = [name, valuetype]
       
  1230         return dic
       
  1231     
       
  1232     def GetCurrentSpecificMenu(self):
       
  1233         if self.CurrentNode:
       
  1234             return self.CurrentNode.GetSpecificMenu()
       
  1235         return []
       
  1236 
       
  1237