00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 from gnosis.xml.pickle import *
00025 from gnosis.xml.pickle.util import setParanoia
00026 setParanoia(0)
00027
00028 from node import *
00029 import eds_utils, gen_cfile
00030
00031 from types import *
00032 import os, re
00033
00034 UndoBufferLength = 20
00035
00036 type_model = re.compile('([\_A-Z]*)([0-9]*)')
00037 range_model = re.compile('([\_A-Z]*)([0-9]*)\[([\-0-9]*)-([\-0-9]*)\]')
00038
00039
00040 CurrentID = 0
00041
00042
00043 def GetNewId():
00044 global CurrentID
00045 CurrentID += 1
00046 return CurrentID
00047
00048 """
00049 Class implementing a buffer of changes made on the current editing Object Dictionary
00050 """
00051
00052 class UndoBuffer:
00053
00054 """
00055 Constructor initialising buffer
00056 """
00057 def __init__(self, currentstate, issaved = False):
00058 self.BufferBuffer = []
00059 self.CurrentIndexCurrentIndex = -1
00060 self.MinIndexMinIndex = -1
00061 self.MaxIndexMaxIndex = -1
00062
00063 if currentstate:
00064 self.CurrentIndexCurrentIndex = 0
00065 self.MinIndexMinIndex = 0
00066 self.MaxIndexMaxIndex = 0
00067
00068 for i in xrange(UndoBufferLength):
00069 if i == 0:
00070 self.BufferBuffer.append(currentstate)
00071 else:
00072 self.BufferBuffer.append(None)
00073
00074 if issaved:
00075 self.LastSaveLastSave = 0
00076 else:
00077 self.LastSaveLastSave = -1
00078
00079 """
00080 Add a new state in buffer
00081 """
00082 def Buffering(self, currentstate):
00083 self.CurrentIndexCurrentIndex = (self.CurrentIndexCurrentIndex + 1) % UndoBufferLength
00084 self.BufferBuffer[self.CurrentIndexCurrentIndex] = currentstate
00085
00086 self.MaxIndexMaxIndex = self.CurrentIndexCurrentIndex
00087 if self.MinIndexMinIndex == self.CurrentIndexCurrentIndex:
00088
00089 if self.LastSaveLastSave == self.MinIndexMinIndex:
00090 self.LastSaveLastSave = -1
00091 self.MinIndexMinIndex = (self.MinIndexMinIndex + 1) % UndoBufferLength
00092 self.MinIndexMinIndex = max(self.MinIndexMinIndex, 0)
00093
00094 """
00095 Return current state of buffer
00096 """
00097 def Current(self):
00098 return self.BufferBuffer[self.CurrentIndexCurrentIndex]
00099
00100 """
00101 Change current state to previous in buffer and return new current state
00102 """
00103 def Previous(self):
00104 if self.CurrentIndexCurrentIndex != self.MinIndexMinIndex:
00105 self.CurrentIndexCurrentIndex = (self.CurrentIndexCurrentIndex - 1) % UndoBufferLength
00106 return self.BufferBuffer[self.CurrentIndexCurrentIndex]
00107 return None
00108
00109 """
00110 Change current state to next in buffer and return new current state
00111 """
00112 def Next(self):
00113 if self.CurrentIndexCurrentIndex != self.MaxIndexMaxIndex:
00114 self.CurrentIndexCurrentIndex = (self.CurrentIndexCurrentIndex + 1) % UndoBufferLength
00115 return self.BufferBuffer[self.CurrentIndexCurrentIndex]
00116 return None
00117
00118 """
00119 Return True if current state is the first in buffer
00120 """
00121 def IsFirst(self):
00122 return self.CurrentIndexCurrentIndex == self.MinIndexMinIndex
00123
00124 """
00125 Return True if current state is the last in buffer
00126 """
00127 def IsLast(self):
00128 return self.CurrentIndexCurrentIndex == self.MaxIndexMaxIndex
00129
00130 """
00131 Note that current state is saved
00132 """
00133 def CurrentSaved(self):
00134 self.LastSaveLastSave = self.CurrentIndexCurrentIndex
00135
00136 """
00137 Return True if current state is saved
00138 """
00139 def IsCurrentSaved(self):
00140 return self.LastSaveLastSave == self.CurrentIndexCurrentIndex
00141
00142
00143
00144 """
00145 Class which control the operations made on the node and answer to view requests
00146 """
00147
00148 class NodeManager:
00149
00150 """
00151 Constructor
00152 """
00153 def __init__(self, cwd):
00154 self.LastNewIndexLastNewIndex = 0
00155 self.FilePathsFilePaths = {}
00156 self.FileNamesFileNames = {}
00157 self.NodeIndexNodeIndex = None
00158 self.CurrentNodeCurrentNode = None
00159 self.ScriptDirectoryScriptDirectory = cwd
00160 self.UndoBuffersUndoBuffers = {}
00161
00162
00163
00164
00165
00166 """
00167 Return the list of types defined for the current node
00168 """
00169 def GetCurrentTypeList(self):
00170 if self.CurrentNodeCurrentNode:
00171 return self.CurrentNodeCurrentNode.GetTypeList()
00172 else:
00173 return ""
00174
00175 """
00176 Return the list of variables that can be mapped for the current node
00177 """
00178 def GetCurrentMapList(self):
00179 if self.CurrentNodeCurrentNode:
00180 return self.CurrentNodeCurrentNode.GetMapList()
00181 else:
00182 return ""
00183
00184
00185
00186
00187
00188 """
00189 Create a new node and add a new buffer for storing it
00190 """
00191 def CreateNewNode(self, name, id, type, description, profile, filepath, NMT, options):
00192
00193 node = Node()
00194
00195 result = self.LoadProfileLoadProfile(profile, filepath, node)
00196 if not result:
00197
00198 self.CurrentNodeCurrentNode = node
00199 self.CurrentNodeCurrentNode.SetNodeName(name)
00200 self.CurrentNodeCurrentNode.SetNodeID(id)
00201 self.CurrentNodeCurrentNode.SetNodeType(type)
00202 self.CurrentNodeCurrentNode.SetNodeDescription(description)
00203 AddIndexList = self.GetMandatoryIndexesGetMandatoryIndexes()
00204 if NMT == "NodeGuarding":
00205 AddIndexList.extend([0x100C, 0x100D])
00206 elif NMT == "Heartbeat":
00207 AddIndexList.append(0x1017)
00208 for option in options:
00209 if option == "DS302":
00210 DS302Path = os.path.join(self.ScriptDirectoryScriptDirectory, "config/DS-302.prf")
00211
00212 if os.path.isfile(DS302Path):
00213 try:
00214 execfile(DS302Path)
00215 self.CurrentNodeCurrentNode.SetDS302Profile(Mapping)
00216 self.CurrentNodeCurrentNode.ExtendSpecificMenu(AddMenuEntries)
00217 except:
00218 return "Problem with DS-302! Syntax Error."
00219 else:
00220 return "Couldn't find DS-302 in 'config' folder!"
00221 elif option == "GenSYNC":
00222 AddIndexList.extend([0x1005, 0x1006])
00223 elif option == "Emergency":
00224 AddIndexList.append(0x1014)
00225 elif option == "SaveConfig":
00226 AddIndexList.extend([0x1010, 0x1011, 0x1020])
00227 elif option == "StoreEDS":
00228 AddIndexList.extend([0x1021, 0x1022])
00229
00230 index = self.AddNodeBufferAddNodeBuffer()
00231 self.SetCurrentFilePathSetCurrentFilePath("")
00232
00233 self.ManageEntriesOfCurrentManageEntriesOfCurrent(AddIndexList, [])
00234 return index
00235 else:
00236 return result
00237
00238 """
00239 Load a profile in node
00240 """
00241 def LoadProfile(self, profile, filepath, node):
00242 if profile != "None":
00243
00244 try:
00245 execfile(filepath)
00246 node.SetProfileName(profile)
00247 node.SetProfile(Mapping)
00248 node.SetSpecificMenu(AddMenuEntries)
00249 return None
00250 except:
00251 return "Syntax Error\nBad OD Profile file!."
00252 else:
00253
00254 node.SetProfileName("None")
00255 node.SetProfile({})
00256 node.SetSpecificMenu([])
00257 return None
00258
00259 """
00260 Open a file and store it in a new buffer
00261 """
00262 def OpenFileInCurrent(self, filepath):
00263
00264 file = open(filepath, "r")
00265 node = load(file)
00266 file.close()
00267 self.CurrentNodeCurrentNode = node
00268
00269 index = self.AddNodeBufferAddNodeBuffer(self.CurrentNodeCurrentNode.Copy(), True)
00270 self.SetCurrentFilePathSetCurrentFilePath(filepath)
00271 return index
00272
00273 """
00274 Save current node in a file
00275 """
00276 def SaveCurrentInFile(self, filepath = None):
00277
00278 if not filepath:
00279 filepath = self.GetCurrentFilePathGetCurrentFilePath()
00280 if filepath == "":
00281 return False
00282
00283 file = open(filepath, "w")
00284 dump(self.CurrentNodeCurrentNode, file)
00285 file.close()
00286 self.SetCurrentFilePathSetCurrentFilePath(filepath)
00287
00288 self.UndoBuffersUndoBuffers[self.NodeIndexNodeIndex].CurrentSaved()
00289 return True
00290
00291 """
00292 Close current state
00293 """
00294 def CloseCurrent(self, ignore = False):
00295
00296 if self.UndoBuffersUndoBuffers[self.NodeIndexNodeIndex].IsCurrentSaved() or ignore:
00297 self.RemoveNodeBufferRemoveNodeBuffer(self.NodeIndexNodeIndex)
00298 return True
00299 return False
00300
00301 """
00302 Import an eds file and store it in a new buffer if no node edited
00303 """
00304 def ImportCurrentFromEDSFile(self, filepath):
00305
00306 result = eds_utils.GenerateNode(filepath, self.ScriptDirectoryScriptDirectory)
00307 if isinstance(result, Node):
00308 self.CurrentNodeCurrentNode = result
00309 if len(self.UndoBuffersUndoBuffers) == 0:
00310 index = self.AddNodeBufferAddNodeBuffer()
00311 self.SetCurrentFilePathSetCurrentFilePath("")
00312 self.BufferCurrentNodeBufferCurrentNode()
00313 return index
00314 else:
00315 return result
00316
00317 """
00318 Export to an eds file and store it in a new buffer if no node edited
00319 """
00320 def ExportCurrentToEDSFile(self, filepath):
00321 return eds_utils.GenerateEDSFile(filepath, self)
00322
00323 """
00324 Build the C definition of Object Dictionary for current node
00325 """
00326 def ExportCurrentToCFile(self, filepath):
00327 return gen_cfile.GenerateFile(filepath, self)
00328
00329
00330
00331
00332
00333 """
00334 Add the specified number of subentry for the given entry. Verify that total
00335 number of subentry (except 0) doesn't exceed nbmax defined
00336 """
00337 def AddSubentriesToCurrent(self, index, number):
00338
00339 length = self.CurrentNodeCurrentNode.GetEntry(index, 0)
00340 infos = self.GetEntryInfosGetEntryInfos(index)
00341 subentry_infos = self.GetSubentryInfosGetSubentryInfos(index, 1)
00342
00343 if "default" in subentry_infos:
00344 default = subentry_infos["default"]
00345 else:
00346 default = self.GetTypeDefaultValueGetTypeDefaultValue(subentry_infos["type"])
00347
00348 if infos["struct"] & OD_IdenticalSubindexes:
00349 for i in xrange(1, min(number,subentry_infos["nbmax"]-length) + 1):
00350 self.CurrentNodeCurrentNode.AddEntry(index, length + i, default)
00351 self.BufferCurrentNodeBufferCurrentNode()
00352
00353 elif infos["struct"] & OD_MultipleSubindexes and 0x2000 <= index <= 0x5FFF:
00354 values = {"name" : "Undefined", "type" : 5, "access" : "rw", "pdo" : True}
00355 for i in xrange(1, min(number,0xFE-length) + 1):
00356 self.CurrentNodeCurrentNode.AddMappingEntry(index, length + i, values = values.copy())
00357 self.CurrentNodeCurrentNode.AddEntry(index, length + i, 0)
00358 self.BufferCurrentNodeBufferCurrentNode()
00359
00360 """
00361 Remove the specified number of subentry for the given entry. Verify that total
00362 number of subentry (except 0) isn't less than 1
00363 """
00364 def RemoveSubentriesFromCurrent(self, index, number):
00365
00366 infos = self.GetEntryInfosGetEntryInfos(index)
00367 length = self.CurrentNodeCurrentNode.GetEntry(index, 0)
00368
00369 if infos["struct"] & OD_IdenticalSubindexes or 0x2000 <= index <= 0x5FFF and infos["struct"] & OD_IdenticalSubindexes:
00370 for i in xrange(min(number, length - 1)):
00371 self.RemoveCurrentVariableRemoveCurrentVariable(index, length - i)
00372 self.BufferCurrentNodeBufferCurrentNode()
00373
00374 """
00375 Add a SDO Server to current node
00376 """
00377 def AddSDOServerToCurrent(self):
00378
00379 if self.CurrentNodeCurrentNode.IsEntry(0x1200):
00380 indexlist = [self.GetLineFromIndexGetLineFromIndex(0x1201)]
00381 if None not in indexlist:
00382 self.ManageEntriesOfCurrentManageEntriesOfCurrent(indexlist, [])
00383
00384 else:
00385 self.ManageEntriesOfCurrentManageEntriesOfCurrent([0x1200], [])
00386
00387 """
00388 Add a SDO Server to current node
00389 """
00390 def AddSDOClientToCurrent(self):
00391 indexlist = [self.GetLineFromIndexGetLineFromIndex(0x1280)]
00392 if None not in indexlist:
00393 self.ManageEntriesOfCurrentManageEntriesOfCurrent(indexlist, [])
00394
00395 """
00396 Add a Transmit PDO to current node
00397 """
00398 def AddPDOTransmitToCurrent(self):
00399 indexlist = [self.GetLineFromIndexGetLineFromIndex(0x1800),self.GetLineFromIndexGetLineFromIndex(0x1A00)]
00400 if None not in indexlist:
00401 self.ManageEntriesOfCurrentManageEntriesOfCurrent(indexlist, [])
00402
00403 """
00404 Add a Receive PDO to current node
00405 """
00406 def AddPDOReceiveToCurrent(self):
00407 indexlist = [self.GetLineFromIndexGetLineFromIndex(0x1400),self.GetLineFromIndexGetLineFromIndex(0x1600)]
00408 if None not in indexlist:
00409 self.ManageEntriesOfCurrentManageEntriesOfCurrent(indexlist, [])
00410
00411 """
00412 Add a list of entries defined in profile for menu item selected to current node
00413 """
00414 def AddSpecificEntryToCurrent(self, menuitem):
00415 indexlist = []
00416 for menu, indexes in self.CurrentNodeCurrentNode.GetSpecificMenu():
00417 if menuitem == menu:
00418 for index in indexes:
00419 indexlist.append(self.GetLineFromIndexGetLineFromIndex(index))
00420 if None not in indexlist:
00421 self.ManageEntriesOfCurrentManageEntriesOfCurrent(indexlist, [])
00422
00423 """
00424 Search the first index available for a pluri entry from base_index
00425 """
00426 def GetLineFromIndex(self, base_index):
00427 found = False
00428 index = base_index
00429 infos = self.GetEntryInfosGetEntryInfos(base_index)
00430 while index < base_index + infos["incr"]*infos["nbmax"] and not found:
00431 if not self.CurrentNodeCurrentNode.IsEntry(index):
00432 found = True
00433 else:
00434 index += infos["incr"]
00435 if found:
00436 return index
00437 return None
00438
00439 """
00440 Add entries specified in addinglist and remove entries specified in removinglist
00441 """
00442 def ManageEntriesOfCurrent(self, addinglist, removinglist):
00443
00444 for index in addinglist:
00445 infos = self.GetEntryInfosGetEntryInfos(index)
00446 if infos["struct"] & OD_MultipleSubindexes:
00447
00448 if infos["struct"] & OD_IdenticalSubindexes:
00449 subentry_infos = self.GetSubentryInfosGetSubentryInfos(index, 1)
00450 if "default" in subentry_infos:
00451 default = subentry_infos["default"]
00452 else:
00453 default = self.GetTypeDefaultValueGetTypeDefaultValue(subentry_infos["type"])
00454 self.CurrentNodeCurrentNode.AddEntry(index, 1, default)
00455
00456 else:
00457 i = 1
00458 subentry_infos = self.GetSubentryInfosGetSubentryInfos(index, i)
00459 while subentry_infos:
00460 if "default" in subentry_infos:
00461 default = subentry_infos["default"]
00462 else:
00463 default = self.GetTypeDefaultValueGetTypeDefaultValue(subentry_infos["type"])
00464 self.CurrentNodeCurrentNode.AddEntry(index, i, default)
00465 i += 1
00466 subentry_infos = self.GetSubentryInfosGetSubentryInfos(index, i)
00467
00468 else:
00469 subentry_infos = self.GetSubentryInfosGetSubentryInfos(index, 0)
00470 if "default" in subentry_infos:
00471 default = subentry_infos["default"]
00472 else:
00473 default = self.GetTypeDefaultValueGetTypeDefaultValue(subentry_infos["type"])
00474 self.CurrentNodeCurrentNode.AddEntry(index, 0, default)
00475
00476 for index in removinglist:
00477 self.RemoveCurrentVariableRemoveCurrentVariable(index)
00478 self.BufferCurrentNodeBufferCurrentNode()
00479
00480
00481 """
00482 Remove an entry from current node. Analize the index to perform the correct
00483 method
00484 """
00485 def RemoveCurrentVariable(self, index, subIndex = None):
00486 Mappings = self.CurrentNodeCurrentNode.GetMappings()
00487 if index < 0x1000 and subIndex == None:
00488 type = self.CurrentNodeCurrentNode.GetEntry(index, 1)
00489 for i in Mappings[-1]:
00490 for value in Mappings[-1][i]["values"]:
00491 if value["type"] == index:
00492 value["type"] = type
00493 self.CurrentNodeCurrentNode.RemoveMappingEntry(index)
00494 self.CurrentNodeCurrentNode.RemoveEntry(index)
00495 elif index == 0x1200 and subIndex == None:
00496 self.CurrentNodeCurrentNode.RemoveEntry(0x1200)
00497 elif 0x1201 <= index <= 0x127F and subIndex == None:
00498 self.CurrentNodeCurrentNode.RemoveLine(index, 0x127F)
00499 elif 0x1280 <= index <= 0x12FF and subIndex == None:
00500 self.CurrentNodeCurrentNode.RemoveLine(index, 0x12FF)
00501 elif 0x1400 <= index <= 0x15FF or 0x1600 <= index <= 0x17FF and subIndex == None:
00502 if 0x1600 <= index <= 0x17FF and subIndex == None:
00503 index -= 0x200
00504 self.CurrentNodeCurrentNode.RemoveLine(index, 0x15FF)
00505 self.CurrentNodeCurrentNode.RemoveLine(index + 0x200, 0x17FF)
00506 elif 0x1800 <= index <= 0x19FF or 0x1A00 <= index <= 0x1BFF and subIndex == None:
00507 if 0x1A00 <= index <= 0x1BFF:
00508 index -= 0x200
00509 self.CurrentNodeCurrentNode.RemoveLine(index, 0x19FF)
00510 self.CurrentNodeCurrentNode.RemoveLine(index + 0x200, 0x1BFF)
00511 else:
00512 found = False
00513 for menu,list in self.CurrentNodeCurrentNode.GetSpecificMenu():
00514 for i in list:
00515 iinfos = self.GetEntryInfosGetEntryInfos(i)
00516 indexes = [i + incr * iinfos["incr"] for incr in xrange(iinfos["nbmax"])]
00517 if index in indexes:
00518 found = True
00519 diff = index - i
00520 for j in list:
00521 jinfos = self.GetEntryInfosGetEntryInfos(j)
00522 self.CurrentNodeCurrentNode.RemoveLine(j + diff, j + jinfos["incr"]*jinfos["nbmax"], jinfos["incr"])
00523 self.CurrentNodeCurrentNode.RemoveMapVariable(index, subIndex)
00524 if not found:
00525 infos = self.GetEntryInfosGetEntryInfos(index)
00526 if not infos["need"]:
00527 self.CurrentNodeCurrentNode.RemoveEntry(index, subIndex)
00528 if index in Mappings[-1]:
00529 self.CurrentNodeCurrentNode.RemoveMappingEntry(index, subIndex)
00530
00531 def AddMapVariableToCurrent(self, index, name, struct, number):
00532 if 0x2000 <= index <= 0x5FFF:
00533 if not self.CurrentNodeCurrentNode.IsEntry(index):
00534 self.CurrentNodeCurrentNode.AddMappingEntry(index, name = name, struct = struct)
00535 if struct == var:
00536 values = {"name" : name, "type" : 0x05, "access" : "rw", "pdo" : True}
00537 self.CurrentNodeCurrentNode.AddMappingEntry(index, 0, values = values)
00538 self.CurrentNodeCurrentNode.AddEntry(index, 0, 0)
00539 else:
00540 values = {"name" : "Number of Entries", "type" : 0x05, "access" : "ro", "pdo" : False}
00541 self.CurrentNodeCurrentNode.AddMappingEntry(index, 0, values = values)
00542 if struct == rec:
00543 values = {"name" : name + " %d[(sub)]", "type" : 0x05, "access" : "rw", "pdo" : True, "nbmax" : 0xFE}
00544 self.CurrentNodeCurrentNode.AddMappingEntry(index, 1, values = values)
00545 for i in xrange(number):
00546 self.CurrentNodeCurrentNode.AddEntry(index, i + 1, 0)
00547 else:
00548 for i in xrange(number):
00549 values = {"name" : "Undefined", "type" : 0x05, "access" : "rw", "pdo" : True}
00550 self.CurrentNodeCurrentNode.AddMappingEntry(index, i + 1, values = values)
00551 self.CurrentNodeCurrentNode.AddEntry(index, i + 1, 0)
00552 self.BufferCurrentNodeBufferCurrentNode()
00553 return None
00554 else:
00555 return "Index 0x%04X already defined!"%index
00556 else:
00557 return "Index 0x%04X isn't a valid index for Map Variable!"%index
00558
00559 def AddUserTypeToCurrent(self, type, min, max, length):
00560 index = 0xA0
00561 while index < 0x100 and self.CurrentNodeCurrentNode.IsEntry(index):
00562 index += 1
00563 if index < 0x100:
00564 customisabletypes = self.GetCustomisableTypesGetCustomisableTypes()
00565 name, valuetype = customisabletypes[type]
00566 size = self.GetEntryInfosGetEntryInfos(type)["size"]
00567 default = self.GetTypeDefaultValueGetTypeDefaultValue(type)
00568 if valuetype == 0:
00569 self.CurrentNodeCurrentNode.AddMappingEntry(index, name = "%s[%d-%d]"%(name, min, max), struct = 3, size = size, default = default)
00570 self.CurrentNodeCurrentNode.AddMappingEntry(index, 0, values = {"name" : "Number of Entries", "type" : 0x05, "access" : "ro", "pdo" : False})
00571 self.CurrentNodeCurrentNode.AddMappingEntry(index, 1, values = {"name" : "Type", "type" : 0x05, "access" : "ro", "pdo" : False})
00572 self.CurrentNodeCurrentNode.AddMappingEntry(index, 2, values = {"name" : "Minimum Value", "type" : type, "access" : "ro", "pdo" : False})
00573 self.CurrentNodeCurrentNode.AddMappingEntry(index, 3, values = {"name" : "Maximum Value", "type" : type, "access" : "ro", "pdo" : False})
00574 self.CurrentNodeCurrentNode.AddEntry(index, 1, type)
00575 self.CurrentNodeCurrentNode.AddEntry(index, 2, min)
00576 self.CurrentNodeCurrentNode.AddEntry(index, 3, max)
00577 elif valuetype == 1:
00578 self.CurrentNodeCurrentNode.AddMappingEntry(index, name = "%s%d"%(name, length), struct = 3, size = length * size, default = default)
00579 self.CurrentNodeCurrentNode.AddMappingEntry(index, 0, values = {"name" : "Number of Entries", "type" : 0x05, "access" : "ro", "pdo" : False})
00580 self.CurrentNodeCurrentNode.AddMappingEntry(index, 1, values = {"name" : "Type", "type" : 0x05, "access" : "ro", "pdo" : False})
00581 self.CurrentNodeCurrentNode.AddMappingEntry(index, 2, values = {"name" : "Length", "type" : 0x05, "access" : "ro", "pdo" : False})
00582 self.CurrentNodeCurrentNode.AddEntry(index, 1, type)
00583 self.CurrentNodeCurrentNode.AddEntry(index, 2, length)
00584 self.BufferCurrentNodeBufferCurrentNode()
00585 return None
00586 else:
00587 return "Too many User Types have already been defined!"
00588
00589
00590
00591
00592
00593 def SetCurrentEntryCallbacks(self, index, value):
00594 if self.CurrentNodeCurrentNode and self.CurrentNodeCurrentNode.IsEntry(index):
00595 entry_infos = self.GetEntryInfosGetEntryInfos(index)
00596 if "callback" not in entry_infos:
00597 self.CurrentNodeCurrentNode.SetParamsEntry(index, None, callback = value)
00598 self.BufferCurrentNodeBufferCurrentNode()
00599
00600 def SetCurrentEntry(self, index, subIndex, value, name, editor):
00601 if self.CurrentNodeCurrentNode and self.CurrentNodeCurrentNode.IsEntry(index):
00602 if name == "value":
00603 if editor == "map":
00604 value = self.CurrentNodeCurrentNode.GetMapValue(value)
00605 if value:
00606 self.CurrentNodeCurrentNode.SetEntry(index, subIndex, value)
00607 elif editor == "bool":
00608 value = value == "True"
00609 self.CurrentNodeCurrentNode.SetEntry(index, subIndex, value)
00610 elif editor == "time":
00611 self.CurrentNodeCurrentNode.SetEntry(index, subIndex, value)
00612 elif editor == "number":
00613 try:
00614 self.CurrentNodeCurrentNode.SetEntry(index, subIndex, int(value))
00615 except:
00616 pass
00617 elif editor == "domain":
00618 try:
00619 if len(value) % 2 != 0:
00620 value = "0" + value
00621 value = value.decode('hex_codec')
00622 self.CurrentNodeCurrentNode.SetEntry(index, subIndex, value)
00623 except:
00624 pass
00625 else:
00626 subentry_infos = self.GetSubentryInfosGetSubentryInfos(index, subIndex)
00627 type = subentry_infos["type"]
00628 dic = {}
00629 for typeindex, typevalue in CustomisableTypes:
00630 dic[typeindex] = typevalue
00631 if type not in dic:
00632 type = self.CurrentNodeCurrentNode.GetEntry(type)[1]
00633 if dic[type] == 0:
00634 try:
00635 value = int(value, 16)
00636 self.CurrentNodeCurrentNode.SetEntry(index, subIndex, value)
00637 except:
00638 pass
00639 else:
00640 self.CurrentNodeCurrentNode.SetEntry(index, subIndex, value)
00641 elif name in ["comment", "save"]:
00642 if editor == "option":
00643 value = value == "Yes"
00644 if name == "save":
00645 self.CurrentNodeCurrentNode.SetParamsEntry(index, subIndex, save = value)
00646 elif name == "comment":
00647 self.CurrentNodeCurrentNode.SetParamsEntry(index, subIndex, comment = value)
00648 else:
00649 if editor == "type":
00650 value = self.GetTypeIndexGetTypeIndex(value)
00651 size = self.GetEntryInfosGetEntryInfos(value)["size"]
00652 self.CurrentNodeCurrentNode.UpdateMapVariable(index, subIndex, size)
00653 elif editor in ["access","raccess"]:
00654 dic = {}
00655 for abbrev,access in AccessType.iteritems():
00656 dic[access] = abbrev
00657 value = dic[value]
00658 if editor == "raccess" and not self.CurrentNodeCurrentNode.IsMappingEntry(index):
00659 entry_infos = self.GetEntryInfosGetEntryInfos(index)
00660 self.CurrentNodeCurrentNode.AddMappingEntry(index, name = entry_infos["name"], struct = 7)
00661 self.CurrentNodeCurrentNode.AddMappingEntry(index, 0, values = self.GetSubentryInfosGetSubentryInfos(index, 0, False).copy())
00662 self.CurrentNodeCurrentNode.AddMappingEntry(index, 1, values = self.GetSubentryInfosGetSubentryInfos(index, 1, False).copy())
00663 self.CurrentNodeCurrentNode.SetMappingEntry(index, subIndex, values = {name : value})
00664 self.BufferCurrentNodeBufferCurrentNode()
00665
00666 def SetCurrentEntryName(self, index, name):
00667 self.CurrentNodeCurrentNode.SetMappingEntry(index, name=name)
00668 self.BufferCurrentNodeBufferCurrentNode()
00669
00670 def SetCurrentUserType(self, index, type, min, max, length):
00671 customisabletypes = self.GetCustomisableTypesGetCustomisableTypes()
00672 values, valuetype = self.GetCustomisedTypeValuesGetCustomisedTypeValues(index)
00673 name, new_valuetype = customisabletypes[type]
00674 size = self.GetEntryInfosGetEntryInfos(type)["size"]
00675 default = self.GetTypeDefaultValueGetTypeDefaultValue(type)
00676 if new_valuetype == 0:
00677 self.CurrentNodeCurrentNode.SetMappingEntry(index, name = "%s[%d-%d]"%(name, min, max), struct = 3, size = size, default = default)
00678 if valuetype == 1:
00679 self.CurrentNodeCurrentNode.SetMappingEntry(index, 2, values = {"name" : "Minimum Value", "type" : type, "access" : "ro", "pdo" : False})
00680 self.CurrentNodeCurrentNode.AddMappingEntry(index, 3, values = {"name" : "Maximum Value", "type" : type, "access" : "ro", "pdo" : False})
00681 self.CurrentNodeCurrentNode.SetEntry(index, 1, type)
00682 self.CurrentNodeCurrentNode.SetEntry(index, 2, min)
00683 if valuetype == 1:
00684 self.CurrentNodeCurrentNode.AddEntry(index, 3, max)
00685 else:
00686 self.CurrentNodeCurrentNode.SetEntry(index, 3, max)
00687 elif new_valuetype == 1:
00688 self.CurrentNodeCurrentNode.SetMappingEntry(index, name = "%s%d"%(name, length), struct = 3, size = size, default = default)
00689 if valuetype == 0:
00690 self.CurrentNodeCurrentNode.SetMappingEntry(index, 2, values = {"name" : "Length", "type" : 0x02, "access" : "ro", "pdo" : False})
00691 self.CurrentNodeCurrentNode.RemoveMappingEntry(index, 3)
00692 self.CurrentNodeCurrentNode.SetEntry(index, 1, type)
00693 self.CurrentNodeCurrentNode.SetEntry(index, 2, length)
00694 if valuetype == 0:
00695 self.CurrentNodeCurrentNode.RemoveEntry(index, 3)
00696 self.BufferCurrentNodeBufferCurrentNode()
00697
00698
00699
00700
00701
00702 def BufferCurrentNode(self):
00703 self.UndoBuffersUndoBuffers[self.NodeIndexNodeIndex].Buffering(self.CurrentNodeCurrentNode.Copy())
00704
00705 def CurrentIsSaved(self):
00706 return self.UndoBuffersUndoBuffers[self.NodeIndexNodeIndex].IsCurrentSaved()
00707
00708 def OneFileHasChanged(self):
00709 result = False
00710 for buffer in self.UndoBuffersUndoBuffers.values():
00711 result |= not buffer.IsCurrentSaved()
00712 return result
00713
00714 def GetBufferNumber(self):
00715 return len(self.UndoBuffersUndoBuffers)
00716
00717 def LoadCurrentPrevious(self):
00718 self.CurrentNodeCurrentNode = self.UndoBuffersUndoBuffers[self.NodeIndexNodeIndex].Previous().Copy()
00719
00720 def LoadCurrentNext(self):
00721 self.CurrentNodeCurrentNode = self.UndoBuffersUndoBuffers[self.NodeIndexNodeIndex].Next().Copy()
00722
00723 def AddNodeBuffer(self, currentstate = None, issaved = False):
00724 self.NodeIndexNodeIndex = GetNewId()
00725 self.UndoBuffersUndoBuffers[self.NodeIndexNodeIndex] = UndoBuffer(currentstate, issaved)
00726 self.FilePathsFilePaths[self.NodeIndexNodeIndex] = ""
00727 self.FileNamesFileNames[self.NodeIndexNodeIndex] = ""
00728 return self.NodeIndexNodeIndex
00729
00730 def ChangeCurrentNode(self, index):
00731 if index in self.UndoBuffersUndoBuffers.keys():
00732 self.NodeIndexNodeIndex = index
00733 self.CurrentNodeCurrentNode = self.UndoBuffersUndoBuffers[self.NodeIndexNodeIndex].Current().Copy()
00734
00735 def RemoveNodeBuffer(self, index):
00736 self.UndoBuffersUndoBuffers.pop(index)
00737 self.FilePathsFilePaths.pop(index)
00738 self.FileNamesFileNames.pop(index)
00739
00740 def GetCurrentNodeIndex(self):
00741 return self.NodeIndexNodeIndex
00742
00743 def GetCurrentFilename(self):
00744 return self.GetFilenameGetFilename(self.NodeIndexNodeIndex)
00745
00746 def GetAllFilenames(self):
00747 indexes = self.UndoBuffersUndoBuffers.keys()
00748 indexes.sort()
00749 return [self.GetFilenameGetFilename(idx) for idx in indexes]
00750
00751 def GetFilename(self, index):
00752 if self.UndoBuffersUndoBuffers[index].IsCurrentSaved():
00753 return self.FileNamesFileNames[index]
00754 else:
00755 return "~%s~"%self.FileNamesFileNames[index]
00756
00757 def SetCurrentFilePath(self, filepath):
00758 self.FilePathsFilePaths[self.NodeIndexNodeIndex] = filepath
00759 if filepath == "":
00760 self.LastNewIndexLastNewIndex += 1
00761 self.FileNamesFileNames[self.NodeIndexNodeIndex] = "Unnamed%d"%self.LastNewIndexLastNewIndex
00762 else:
00763 self.FileNamesFileNames[self.NodeIndexNodeIndex] = os.path.splitext(os.path.basename(filepath))[0]
00764
00765 def GetCurrentFilePath(self):
00766 if len(self.FilePathsFilePaths) > 0:
00767 return self.FilePathsFilePaths[self.NodeIndexNodeIndex]
00768 else:
00769 return ""
00770
00771 def GetCurrentBufferState(self):
00772 first = self.UndoBuffersUndoBuffers[self.NodeIndexNodeIndex].IsFirst()
00773 last = self.UndoBuffersUndoBuffers[self.NodeIndexNodeIndex].IsLast()
00774 return not first, not last
00775
00776
00777
00778
00779
00780 def GetCurrentCommunicationLists(self):
00781 list = []
00782 for index in MappingDictionary.iterkeys():
00783 if 0x1000 <= index < 0x1200:
00784 list.append(index)
00785 return self.GetProfileListsGetProfileLists(MappingDictionary, list)
00786
00787 def GetCurrentDS302Lists(self):
00788 return self.GetSpecificProfileListsGetSpecificProfileLists(self.CurrentNodeCurrentNode.GetDS302Profile())
00789
00790 def GetCurrentProfileLists(self):
00791 return self.GetSpecificProfileListsGetSpecificProfileLists(self.CurrentNodeCurrentNode.GetProfile())
00792
00793 def GetSpecificProfileLists(self, mappingdictionary):
00794 validlist = []
00795 exclusionlist = []
00796 for name, list in self.CurrentNodeCurrentNode.GetSpecificMenu():
00797 exclusionlist.extend(list)
00798 for index in mappingdictionary.iterkeys():
00799 if index not in exclusionlist:
00800 validlist.append(index)
00801 return self.GetProfileListsGetProfileLists(mappingdictionary, validlist)
00802
00803 def GetProfileLists(self, mappingdictionary, list):
00804 dictionary = {}
00805 current = []
00806 for index in list:
00807 dictionary[index] = (mappingdictionary[index]["name"], mappingdictionary[index]["need"])
00808 if self.CurrentNodeCurrentNode.IsEntry(index):
00809 current.append(index)
00810 return dictionary, current
00811
00812 def GetCurrentNextMapIndex(self):
00813 if self.CurrentNodeCurrentNode:
00814 index = 0x2000
00815 while self.CurrentNodeCurrentNode.IsEntry(index) and index < 0x5FFF:
00816 index += 1
00817 if index < 0x6000:
00818 return index
00819 else:
00820 return None
00821
00822 def CurrentDS302Defined(self):
00823 if self.CurrentNodeCurrentNode:
00824 return len(self.CurrentNodeCurrentNode.GetDS302Profile()) > 0
00825 return False
00826
00827
00828
00829
00830
00831 def GetCurrentNodeName(self):
00832 if self.CurrentNodeCurrentNode:
00833 return self.CurrentNodeCurrentNode.GetNodeName()
00834 else:
00835 return ""
00836
00837 def GetCurrentNodeID(self):
00838 if self.CurrentNodeCurrentNode:
00839 return self.CurrentNodeCurrentNode.GetNodeID()
00840 else:
00841 return None
00842
00843 def GetCurrentNodeInfos(self):
00844 name = self.CurrentNodeCurrentNode.GetNodeName()
00845 id = self.CurrentNodeCurrentNode.GetNodeID()
00846 type = self.CurrentNodeCurrentNode.GetNodeType()
00847 description = self.CurrentNodeCurrentNode.GetNodeDescription()
00848 return name, id, type, description
00849
00850 def SetCurrentNodeInfos(self, name, id, type, description):
00851 self.CurrentNodeCurrentNode.SetNodeName(name)
00852 self.CurrentNodeCurrentNode.SetNodeID(id)
00853 self.CurrentNodeCurrentNode.SetNodeType(type)
00854 self.CurrentNodeCurrentNode.SetNodeDescription(description)
00855 self.BufferCurrentNodeBufferCurrentNode()
00856
00857 def GetCurrentProfileName(self):
00858 if self.CurrentNodeCurrentNode:
00859 return self.CurrentNodeCurrentNode.GetProfileName()
00860 return ""
00861
00862 def IsCurrentEntry(self, index):
00863 if self.CurrentNodeCurrentNode:
00864 return self.CurrentNodeCurrentNode.IsEntry(index)
00865 return False
00866
00867 def GetCurrentEntry(self, index, subIndex = None):
00868 if self.CurrentNodeCurrentNode:
00869 return self.CurrentNodeCurrentNode.GetEntry(index, subIndex)
00870 return None
00871
00872 def GetCurrentParamsEntry(self, index, subIndex = None):
00873 if self.CurrentNodeCurrentNode:
00874 return self.CurrentNodeCurrentNode.GetParamsEntry(index, subIndex)
00875 return None
00876
00877 def GetCurrentValidIndexes(self, min, max):
00878 validindexes = []
00879 for index in self.CurrentNodeCurrentNode.GetIndexes():
00880 if min <= index <= max:
00881 validindexes.append((self.GetEntryNameGetEntryName(index), index))
00882 return validindexes
00883
00884 def GetCurrentValidChoices(self, min, max):
00885 validchoices = []
00886 exclusionlist = []
00887 for menu, indexes in self.CurrentNodeCurrentNode.GetSpecificMenu():
00888 exclusionlist.extend(indexes)
00889 good = True
00890 for index in indexes:
00891 good &= min <= index <= max
00892 if good:
00893 validchoices.append((menu, None))
00894 list = [index for index in MappingDictionary.keys() if index >= 0x1000]
00895 profiles = self.CurrentNodeCurrentNode.GetMappings(False)
00896 for profile in profiles:
00897 list.extend(profile.keys())
00898 list.sort()
00899 for index in list:
00900 if min <= index <= max and not self.CurrentNodeCurrentNode.IsEntry(index) and index not in exclusionlist:
00901 validchoices.append((self.GetEntryNameGetEntryName(index), index))
00902 return validchoices
00903
00904 def HasCurrentEntryCallbacks(self, index):
00905 if self.CurrentNodeCurrentNode and self.CurrentNodeCurrentNode.IsEntry(index):
00906 entry_infos = self.GetEntryInfosGetEntryInfos(index)
00907 if "callback" in entry_infos:
00908 return entry_infos["callback"]
00909 return self.CurrentNodeCurrentNode.HasEntryCallbacks(index)
00910 return False
00911
00912 def GetCurrentEntryValues(self, index):
00913 if self.CurrentNodeCurrentNode:
00914 return self.GetNodeEntryValuesGetNodeEntryValues(self.CurrentNodeCurrentNode, index)
00915
00916 def GetNodeEntryValues(self, node, index):
00917 if node and node.IsEntry(index):
00918 entry_infos = node.GetEntryInfos(index)
00919 data = []
00920 editors = []
00921 values = node.GetEntry(index)
00922 params = node.GetParamsEntry(index)
00923 if type(values) == ListType:
00924 for i, value in enumerate(values):
00925 data.append({"value" : value})
00926 data[-1].update(params[i])
00927 else:
00928 data.append({"value" : values})
00929 data[-1].update(params)
00930 for i, dic in enumerate(data):
00931 infos = node.GetSubentryInfos(index, i)
00932 dic["subindex"] = "0x%02X"%i
00933 dic["name"] = infos["name"]
00934 dic["type"] = node.GetTypeName(infos["type"])
00935 dic["access"] = AccessType[infos["access"]]
00936 dic["save"] = OptionType[dic["save"]]
00937 editor = {"subindex" : None, "save" : "option", "callback" : "option", "comment" : "string"}
00938 if type(values) == ListType and i == 0:
00939 editor["name"] = None
00940 editor["type"] = None
00941 if 0x1600 <= index <= 0x17FF or 0x1A00 <= index <= 0x1C00:
00942 editor["access"] = "raccess"
00943 else:
00944 editor["access"] = None
00945 editor["value"] = None
00946 else:
00947 if infos["user_defined"]:
00948 if entry_infos["struct"] & OD_IdenticalSubindexes:
00949 editor["name"] = None
00950 if i > 1:
00951 editor["type"] = None
00952 editor["access"] = None
00953 else:
00954 editor["type"] = "type"
00955 editor["access"] = "access"
00956 else:
00957 if entry_infos["struct"] & OD_MultipleSubindexes:
00958 editor["name"] = "string"
00959 else:
00960 editor["name"] = None
00961 editor["type"] = "type"
00962 editor["access"] = "access"
00963 else:
00964 editor["name"] = None
00965 editor["type"] = None
00966 editor["access"] = None
00967 if index < 0x260:
00968 editor["value"] = None
00969 if i == 1:
00970 dic["value"] = node.GetTypeName(dic["value"])
00971 elif 0x1600 <= index <= 0x17FF or 0x1A00 <= index <= 0x1C00:
00972 editor["value"] = "map"
00973 dic["value"] = node.GetMapName(dic["value"])
00974 else:
00975 if dic["type"].startswith("VISIBLE_STRING"):
00976 editor["value"] = "string"
00977 elif dic["type"] in ["TIME_OF_DAY","TIME_DIFFERENCE"]:
00978 editor["value"] = "time"
00979 elif dic["type"] == "DOMAIN":
00980 editor["value"] = "domain"
00981 dic["value"] = dic["value"].encode('hex_codec')
00982 elif dic["type"] == "BOOLEAN":
00983 editor["value"] = "bool"
00984 dic["value"] = BoolType[dic["value"]]
00985 result = type_model.match(dic["type"])
00986 if result:
00987 values = result.groups()
00988 if values[0] == "UNSIGNED":
00989 format = "0x%0" + str(int(values[1])/4) + "X"
00990 dic["value"] = format%dic["value"]
00991 editor["value"] = "string"
00992 if values[0] == "INTEGER":
00993 editor["value"] = "number"
00994 elif values[0] == "REAL":
00995 editor["value"] = "float"
00996 elif values[0] == "VISIBLE_STRING":
00997 editor["length"] = values[0]
00998 result = range_model.match(dic["type"])
00999 if result:
01000 values = result.groups()
01001 if values[0] in ["UNSIGNED", "INTEGER", "REAL"]:
01002 editor["min"] = values[2]
01003 editor["max"] = values[3]
01004 editors.append(editor)
01005 return data, editors
01006 else:
01007 return None
01008
01009
01010
01011
01012
01013 def GetCustomisedTypeValues(self, index):
01014 if self.CurrentNodeCurrentNode:
01015 values = self.CurrentNodeCurrentNode.GetEntry(index)
01016 customisabletypes = self.GetCustomisableTypesGetCustomisableTypes()
01017 return values, customisabletypes[values[1]][1]
01018 else:
01019 return None, None
01020
01021 def GetEntryName(self, index):
01022 if self.CurrentNodeCurrentNode:
01023 return self.CurrentNodeCurrentNode.GetEntryName(index)
01024 else:
01025 return FindEntryName(index, MappingDictionary)
01026
01027 def GetEntryInfos(self, index):
01028 if self.CurrentNodeCurrentNode:
01029 return self.CurrentNodeCurrentNode.GetEntryInfos(index)
01030 else:
01031 return FindEntryInfos(index, MappingDictionary)
01032
01033 def GetSubentryInfos(self, index, subindex):
01034 if self.CurrentNodeCurrentNode:
01035 return self.CurrentNodeCurrentNode.GetSubentryInfos(index, subindex)
01036 else:
01037 result = FindSubentryInfos(index, subindex, MappingDictionary)
01038 if result:
01039 result["user_defined"] = False
01040 return result
01041
01042 def GetTypeIndex(self, typename):
01043 if self.CurrentNodeCurrentNode:
01044 return self.CurrentNodeCurrentNode.GetTypeIndex(typename)
01045 else:
01046 return FindTypeIndex(typename, MappingDictionary)
01047
01048 def GetTypeName(self, typeindex):
01049 if self.CurrentNodeCurrentNode:
01050 return self.CurrentNodeCurrentNode.GetTypeName(typeindex)
01051 else:
01052 return FindTypeName(typeindex, MappingDictionary)
01053
01054 def GetTypeDefaultValue(self, typeindex):
01055 if self.CurrentNodeCurrentNode:
01056 return self.CurrentNodeCurrentNode.GetTypeDefaultValue(typeindex)
01057 else:
01058 return FindTypeDefaultValue(typeindex, MappingDictionary)
01059
01060 def GetMapVariableList(self):
01061 if self.CurrentNodeCurrentNode:
01062 return self.CurrentNodeCurrentNode.GetMapVariableList()
01063 else:
01064 return []
01065
01066 def GetMandatoryIndexes(self, node = None):
01067 if self.CurrentNodeCurrentNode:
01068 return self.CurrentNodeCurrentNode.GetMapVariableList()
01069 else:
01070 return FindMandatoryIndexes(MappingDictionary)
01071
01072 def GetCustomisableTypes(self):
01073 dic = {}
01074 for index, valuetype in CustomisableTypes:
01075 name = self.GetTypeNameGetTypeName(index)
01076 dic[index] = [name, valuetype]
01077 return dic
01078
01079 def GetCurrentSpecificMenu(self):
01080 if self.CurrentNodeCurrentNode:
01081 return self.CurrentNodeCurrentNode.GetSpecificMenu()
01082 return []
01083