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