def absPath(path, source=''): if path is None or not path: return None if not os.path.exists(path): return None if os.path.isabs(path): return toUnixPath(path) return toUnixPath(os.path.abspath(path))
def __getPathStr(self, _path, proj_path): path = relativePath(_path, proj_path) # getting relative path if path is None or not path: return tuple() temp = os.path.join(os.path.dirname(proj_path), path) # getting full path temp = toUnixPath(os.path.normpath(temp)) if not os.path.exists(temp): return tuple([temp]) path = toUnixPath(path) temp = toUnixPath(temp) return tuple([path, temp])
def __getPath(self, xml_node, proj_path): path = xml_node.getAttribute('path') path = relativePath(path, proj_path) # getting relative path if path is None or not path: return tuple() temp = os.path.join(os.path.dirname(proj_path), path) # getting full path temp = os.path.normpath(temp) if not os.path.exists(temp): return tuple([temp]) path = toUnixPath(path) temp = toUnixPath(temp) return tuple([path, temp])
def __getExternals(self, treeNode, filename): external_files = [] nodeType = treeNode.type() if nodeType.isLink(): if nodeType.linkTargetTag: strings = treeNode.target.split('/') if len(strings) > 1: strings.pop() targetFile = '/'.join(strings) if targetFile != filename: external_files.append( toUnixPath( os.path.relpath(targetFile, os.path.dirname(filename)))) return external_files if treeNode.nodeDesc() is not None: for c in treeNode.allChildren(): if c in treeNode.nodeDesc().childClasses and c in nodeType: children = treeNode.children(c) for child in children: external_files.extend( self.__getExternals(child, filename)) return external_files
def __openDiagramShapes(self, projdata, the_proj): shapes = projdata.getElementsByTagName('shapelib') if shapes and shapes[0].hasAttribute('path'): plist = self.__getPathWithCommonChecking(shapes[0], the_proj) if len(plist) == 2: the_proj.shapelib = shapelib.ShapeLib() if not the_proj.shapelib.init(plist[1]): print('warning: Can\'t load shape library from \"{0}\".'.format(plist[1])) the_proj.shapelib = None elif plist: print('warning: Can\'t load shape library from \"{0}\".'.format(plist[0])) else: print('warning: Can\'t load shape library from \"{0}\".'.format(shapes[0])) if the_proj.shapelib is None: print('info: Trying to load default diagram shapes...') try_paths = [] if isinstance(globals.applicationShapesPath, list): try_paths = globals.applicationShapesPath else: try_paths.append(globals.applicationShapesPath) okay = False err = False for path in try_paths: the_file = path if the_file is None: print('error: Unexpected error: empty path to diagram shapes file!') continue if not os.path.isabs(the_file): print('debug: generating absPath for \"{0}\" relative to \"{1}\"'.format(the_file, globals.rootDirectory)) the_file = absPath(the_file, globals.rootDirectory) # make full path from relative path else: print('debug: the path \"%s\" is abs!' % the_file) the_file = toUnixPath(the_file) if the_file is None: err = True print(u'warning: Diagram shapes file \"{0}\" does not exist!'.format(path)) continue if not os.path.exists(the_file): err = True print(u'warning: Diagram shapes file \"{0}\" does not exist!'.format(the_file)) continue the_proj.shapelib = shapelib.ShapeLib() if not the_proj.shapelib.init(the_file): print('warning: Can\'t load shape library from \"{0}\".'.format(the_file)) the_proj.shapelib = None continue okay = True return
def __openAlphabetFile(self, projdata, the_proj): alphs = projdata.getElementsByTagName('alphabet') if alphs and alphs[0].hasAttribute('path'): plist = self.__getPathWithCommonChecking(alphs[0], the_proj) if len(plist) == 2: the_proj.alphabet = alphabet.Alphabet() if not the_proj.alphabet.load(plist[1]) or len(the_proj.alphabet) < 1: print('warning: Can\'t load alphabet from \'{0}\'!'.format(plist[1])) print('') the_proj.alphabet = None else: print('ok: Alphabet file \'{0}\' was loaded successfully'.format(plist[1])) print('') return elif plist: print('warning: Can\'t load alphabet from \"{0}\".'.format(plist[0])) else: print('warning: Can\'t load alphabet from \"{0}\".'.format(alphs[0])) if the_proj.alphabet is None: print('info: Trying to load default behavior alphabet...') try_paths = [] if isinstance(globals.applicationAlphabetPath, list): try_paths = globals.applicationAlphabetPath else: try_paths.append(globals.applicationAlphabetPath) okay = False err = False for path in try_paths: the_file = path if not os.path.isabs(the_file): the_file = absPath(the_file, globals.rootDirectory) # make full path from relative path else: the_file = toUnixPath(the_file) if the_file is None: err = True print(u'warning: Alphabet file \"{0}\" does not exist!'.format(path)) continue if not os.path.exists(the_file): err = True print(u'warning: Alphabet file \"{0}\" does not exist!'.format(the_file)) continue the_proj.alphabet = alphabet.Alphabet() if not the_proj.alphabet.load(the_file) or len(the_proj.alphabet) < 1: print('warning: Can\'t load alphabet from \'{0}\'!'.format(the_file)) print('') the_proj.alphabet = None continue okay = True print('ok: Alphabet file \'{0}\' was loaded successfully'.format(the_file)) print('') return
def __init__(self, project, filename, parent=None): TL_AbstractItem.__init__(self, parent) self.path = filename filedir = toUnixPath(os.path.dirname(filename)) + '/' # text = filename text = filename.replace(filedir, '') self.setText(0, text) self.setToolTip(0, self.path) subbranches = project.trees.getBranchesByFile(self.path, project.nodes) if subbranches: for t in subbranches: TL_AbstractItem.addChild(self, TL_TaskItem(subbranches[t], self)) if self.childCount() > 1: self.sortChildren(0, Qt.AscendingOrder)
def __loadLibrary(self, libraries, filename): if not filename: return 0 print('info: Parsing "{0}" ...'.format(filename)) dom = parse(filename) data = dom.getElementsByTagName(self.__alphabet.headerLibrary) if not data: data = dom.getElementsByTagName("libraries") if not data: print( "error: Wrong library file! It has no tags '{0}' and 'libraries'.".format( self.__alphabet.headerLibrary ) ) print("") return 0 filename = toUnixPath(os.path.normpath(os.path.abspath(filename))) libs = data[0].getElementsByTagName("library") libs.extend(data[0].getElementsByTagName("Library")) outerlibs = data[0].getElementsByTagName("include") num_loaded = 0 # Loading libraries: for lib in libs: library = self.__parseLib(libraries, lib) if library is not None: library.setPath(filename) libraries[library.libname] = library num_loaded += 1 # Reading external files: if outerlibs: libpaths = [] for outer in outerlibs: libpaths.append(outer.getAttribute("path")) num_loaded += self.__loadLibraries(libraries, libpaths, filename) if num_loaded == 0: print("WARNING: No libraries found!") print("") return num_loaded
def __loadLibrary(self, libraries, filename): if not filename: return 0 print('info: Parsing \"{0}\" ...'.format(filename)) dom = parse(filename) data = dom.getElementsByTagName(self.__alphabet.headerLibrary) if not data: data = dom.getElementsByTagName('libraries') if not data: print( 'error: Wrong library file! It has no tags \'{0}\' and \'libraries\'.' .format(self.__alphabet.headerLibrary)) print('') return 0 filename = toUnixPath(os.path.normpath(os.path.abspath(filename))) libs = data[0].getElementsByTagName('library') libs.extend(data[0].getElementsByTagName('Library')) outerlibs = data[0].getElementsByTagName('include') num_loaded = 0 # Loading libraries: for lib in libs: library = self.__parseLib(libraries, lib) if library is not None: library.setPath(filename) libraries[library.libname] = library num_loaded += 1 # Reading external files: if outerlibs: libpaths = [] for outer in outerlibs: libpaths.append(outer.getAttribute('path')) num_loaded += self.__loadLibraries(libraries, libpaths, filename) if num_loaded == 0: print('WARNING: No libraries found!') print('') return num_loaded
def __getExternals(self, treeNode, filename): external_files = [] nodeType = treeNode.type() if nodeType.isLink(): if nodeType.linkTargetTag: strings = treeNode.target.split('/') if len(strings) > 1: strings.pop() targetFile = '/'.join(strings) if targetFile != filename: external_files.append(toUnixPath(os.path.relpath(targetFile, os.path.dirname(filename)))) return external_files if treeNode.nodeDesc() is not None: for c in treeNode.allChildren(): if c in treeNode.nodeDesc().childClasses and c in nodeType: children = treeNode.children(c) for child in children: external_files.extend(self.__getExternals(child, filename)) return external_files
def _readConfig(args): settings = QSettings('Victor Zarubkin', 'Behavior Studio') if socket.gethostname().lower() == 'victor': settings.beginGroup('startup') value = settings.value('showLogo') if value is not None: value = value.lower() if value in ('true', 'false'): globals.showLogo = value == 'true' settings.endGroup() else: globals.showLogo = True currDir = os.getcwd( ) # os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # Reading application config file: configFile = None data = None try_configs = [] if isinstance(args.config_file, list): try_configs = args.config_file else: try_configs.append(args.config_file) okay = False err = False for conf in try_configs: configFile = conf data = None if not os.path.isabs(configFile): configFile = absPath(configFile, currDir) # make full path from relative path else: configFile = toUnixPath(configFile) if configFile is None: err = True print(u'warning: Config file \"{0}\" does not exist!'.format(conf)) continue if not os.path.exists(configFile): err = True print(u'warning: Config file \"{0}\" does not exist!'.format( configFile)) continue dom = parse(configFile) data = dom.getElementsByTagName('config') if not data: err = True print( u'warning: Config file \"{0}\" is wrong formatted! It must have header \"<config>\".' .format(configFile)) continue okay = True break if not okay: print('error: Can\'t load application configuration!') print('') return False globals.loadedApplicationConfigFile = configFile if err: print('') _readConfigIcons(configFile, data[0]) return True
def main(argv): # Create a Qt application app = QApplication(argv) app.setStyle('macintosh') setPalette(app) eng_package_error_message, rus_package_error_message = _checkPackages() if eng_package_error_message or rus_package_error_message: error_message = u'<font color=\"red\">Next python packages are required for running the program:</font><br/>' error_message += eng_package_error_message error_message += u'<br/><font color=\"yellow\">---------------------------------' \ u'-------------------------------------------------</font><br/>' error_message += u'<font color=\"red\">Для запуска программы необходимы следующие библиотеки для python:' \ u'</font><br/>' error_message += rus_package_error_message mb = QMessageBox(QMessageBox.Critical, 'Package Error', error_message, QMessageBox.Ok) mb.exec_() sys.exit() from main_window import AppArgs, MainWindow start_path = os.environ.get('BEHAVIOR_STUDIO_ROOT', None) if start_path is None: globals.rootDirectory = os.getcwd() # globals.rootDirectory = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) else: globals.rootDirectory = start_path globals.rootDirectory = toUnixPath(os.path.normpath(globals.rootDirectory)) # Read input args appArgs = AppArgs(argv) opts = None try: opts, args = getopt.getopt( argv[1:], 'hdc:', ['help', 'debug', 'config=', 'config-file=']) except getopt.GetoptError: appArgs.options_error = True mb = QMessageBox( QMessageBox.Warning, 'Options Error', '<font color=\"red\">There are some options error!<br/>Read studio output...</font>', QMessageBox.Ok) mb.exec_() if not appArgs.options_error: for opt, arg in opts: if opt in ('-h', '--help'): infoString = 'available options:<br/>\ -h, --help - see this hint<br/>\ -c, --config, --config-file - set start configuration file<br/>' infoString += '<br/>Example:<br/><b>{0} -c config.xml</b>'.format( appArgs.current_file) mb = QMessageBox(QMessageBox.Information, 'Options Help', infoString, QMessageBox.Ok) mb.exec_() sys.exit() elif opt in ('-c', '--config', '--config-file'): appArgs.config_file = arg appArgs.config_file_default = False elif opt in ('-d', '--debug'): appArgs.debug = True globals.applicationConfigFile = globals.processVars( globals.applicationConfigFile) appArgs.config_file = globals.processVars(appArgs.config_file) globals.applicationAlphabetPath = globals.processVars( globals.applicationAlphabetPath) globals.applicationShapesPath = globals.processVars( globals.applicationShapesPath) if args: appArgs.project_for_opening = toUnixPath(args[0]) if not _readConfig(appArgs): # read icons path mb = QMessageBox( QMessageBox.Critical, 'Configuration Error', 'Can\'t load application configuration!<br/>' 'Configuration file <b>\'{0}\'</b> does not exist.'.format( appArgs.config_file), QMessageBox.Ok) mb.exec_() sys.exit() if globals.showLogo: splash = QSplashScreen( QPixmap(joinPath(globals.applicationIconsPath, 'splash2.png'))) splash.showMessage( '<h2>Behavior Studio {0}</h2>'.format(globals.strVersion), Qt.AlignHCenter, Qt.red) splash.show() sleep(3) else: splash = None # Create main window window = MainWindow(appArgs) window.show() if splash is not None: splash.finish(window) # window = main_window.MainStackedWindow() # window.hide() # Enter Qt application main loop app.exec_() sys.exit()
def __saveNode(self, filename, xml, parentXmlNode, treeNode, diagramXml, parentDiagramXmlNode): nodeCls = treeNode.cls() # add new Node to xml curr = xml.createElement(nodeCls.tag) parentXmlNode.appendChild(curr) diagramCurr = diagramXml.createElement(nodeCls.tag) parentDiagramXmlNode.appendChild(diagramCurr) # save reference if treeNode.refname() and nodeCls.linkTag: curr.setAttribute(nodeCls.linkTag, treeNode.refname()) # save type nodeType = treeNode.type() typename = '' if nodeCls.debuggable and treeNode.debug is True: typename += 'debug ' typename += nodeType.name curr.setAttribute('Type', typename) # save unique id curr.setAttribute('uid', str(treeNode.uid())) if nodeType.isLink(): # save reference target if nodeType.linkTargetTag: strings = treeNode.target.split('/') if len(strings) > 1: targetRef = strings[-1] curr.setAttribute(nodeType.linkTargetTag, targetRef) strings.pop() targetFile = '/'.join(strings) if targetFile != filename: tfile = toUnixPath(os.path.relpath(targetFile, os.path.dirname(filename))) curr.setAttribute('File', tfile) # save diagram data self.__saveDigramData(treeNode.uid(), treeNode.diagramInfo, diagramCurr) return curr elif nodeType.singleblockEnabled and treeNode.singleBlock(): curr.setAttribute('singleBlock', '1') # save node name nodename = '' if treeNode.isInverse(): nodename += '!' nodename += treeNode.nodeName curr.setAttribute('Name', nodename) desc = treeNode.nodeDesc() if desc is not None and desc.creator: # save creator creatorName = '' if treeNode.isInverse(): creatorName += '!' creatorName += desc.creator curr.setAttribute('Creator', creatorName) # save library curr.setAttribute(nodeCls.lib, treeNode.libname) # save attributes if nodeCls.attributes.tag: settings = xml.createElement(nodeCls.attributes.tag) curr.appendChild(settings) tags = dict() for attrName in treeNode.attributes(): attr = treeNode.attributes()[attrName] attrDesc = attr.attrDesc() if attrDesc is None: treename = treeNode.root().refname() print('warning: Node \'{0}\' of tree \'{1}\' has no attribute \'{2}\'. \ This attribute will not be saved.'.format(treeNode.nodeName, treename, attrName)) continue if attrDesc.isArray(): strVals = attr.valueToStr() if not strVals or not attrDesc.subtags: continue elem = settings last = len(attrDesc.subtags) - 1 for i in range(last): sub = attrDesc.subtags[i] if sub in tags: elem = tags[sub][0] continue newElem = xml.createElement(sub) tags[sub] = [newElem] elem.appendChild(newElem) elem = newElem lastSub = attrDesc.subtags[last] i = 0 for value in strVals: n = i + 1 if lastSub in tags: if len(tags[lastSub]) < n: newElem = xml.createElement(lastSub) tags[lastSub].append(newElem) elem.appendChild(newElem) curElem = newElem else: curElem = tags[lastSub][i] else: newElem = xml.createElement(lastSub) tags[lastSub] = [newElem] elem.appendChild(newElem) curElem = newElem curElem.setAttribute(attrDesc.attrname, value) i += 1 else: elem = settings for sub in attrDesc.subtags: if sub in tags: elem = tags[sub][0] continue newElem = xml.createElement(sub) tags[sub] = [newElem] elem.appendChild(newElem) elem = newElem value = attr.valueToStr() elem.setAttribute(attrDesc.attrname, value) # save diagram data self.__saveDigramData(treeNode.uid(), treeNode.diagramInfo, diagramCurr) # save children if treeNode.nodeDesc() is not None: ccc = [] for c in treeNode.allChildren(): if c in treeNode.nodeDesc().childClasses and c in nodeType: ccc.append(c) ccc.sort() for c in ccc: children = treeNode.children(c) max_children = nodeType.child(c).max num_children = 0 for child in children: if self.__saveNode(filename, xml, curr, child, diagramXml, diagramCurr) is not None: num_children += 1 if num_children >= max_children: break return curr
def __parseNode(self, version, project, bt, nodes, currFile, cls, node, parent, diagramNode): global _versionWithUids if node.hasAttribute('Name'): name = node.getAttribute('Name') else: name = '' if not name: print('ERROR: Each node requires tag \"Name\"!') return None if node.hasAttribute('Type'): nodeType = node.getAttribute('Type') else: nodeType = '' if not nodeType: print('ERROR: Each node requires tag \"Type\"!') return None strings = nodeType.split(' ') nodeType = strings[-1] if nodeType not in cls: print('error: Type \"{0}\" is not specified for class \"{1}\".'.format(nodeType, cls.name)) return None # read diagram info: diagramInfo, diagramUid = self.__readDiagramInfo(diagramNode) isInverse = False if '!' in name or '~' in name: isInverse = True name = name.replace('!', '') name = name.replace('~', '') name = name.strip() # Checking for debug usage: isDebug = False if len(strings) > 1 and cls.debuggable and strings[0] in self.__debug_str: isDebug = True # Checking for single-block: isSingleBlock = False if node.hasAttribute('singleBlock'): sb = node.getAttribute('singleBlock').lower() if sb not in ('0', 'no', 'false'): isSingleBlock = True # Getting uid for node: if node.hasAttribute('uid'): u = node.getAttribute('uid') if u: uid = int(u) else: uid = None else: uid = None subType = cls.get(nodeType) if subType.isLink(): isSingleBlock = False target = '' if node.hasAttribute(subType.targetTag()): target = node.getAttribute(subType.targetTag()) if not target: print('error: All links must have target! (tag <{0}> is missing)'.format(subType.targetTag())) return None filename = '' if node.hasAttribute('File'): filename = node.getAttribute('File') if not os.path.isabs(filename): realpath = '/'.join([os.path.dirname(currFile), filename]) filename = os.path.normpath(os.path.abspath(realpath)) filename = toUnixPath(filename) if not os.path.exists(filename): filename = '' if not filename: filename = currFile branchRef = fullTreeName(filename, target) if branchRef in bt or branchRef in project.trees: newNode = treenode.TreeNode(project, node, cls.name, nodeType, isDebug, uid) newNode.target = branchRef newNode.setPath(currFile) if diagramUid == newNode.uid() or version < _versionWithUids: newNode.diagramInfo = diagramInfo if newNode.uid() in nodes: print('error: Node with uid \"{0}\" already exist in current file!'.format(newNode.uid())) return None if newNode.uid() in project.nodes: print('error: Node with uid \"{0}\" already exist in current project!'.format(newNode.uid())) return None nodes.add(newNode, False) return newNode print('error: Link to \"{0}\" is not found neither in file \"{1}\" nor in current project!' .format(target, filename)) return None elif not subType.singleblockEnabled: isSingleBlock = False if node.hasAttribute(cls.lib): libname = node.getAttribute(cls.lib) else: libname = '' if not libname: print('error: Each \"{0}\" node requires tag \"{1}\"!'.format(cls.name, cls.lib)) return None newNode = treenode.TreeNode(project, node, cls.name, nodeType, isDebug, uid) if newNode.uid() in nodes: print('error: Node with uid \"{0}\" already exist in current file!'.format(newNode.uid())) return None if newNode.uid() in project.nodes: print('error: Node with uid \"{0}\" already exist in current project!'.format(newNode.uid())) return None nodes.add(newNode, False) newNode.setSingleblock(isSingleBlock) newNode.setLibName(libname) newNode.setNodeName(name) newNode.setPath(currFile) if diagramUid == newNode.uid() or version < _versionWithUids: newNode.diagramInfo = diagramInfo if isInverse: newNode.setInverse(isInverse) # Read branch name:-------------------------------------------------------------- if cls.top: if node.hasAttribute(cls.linkTag): ref = node.getAttribute(cls.linkTag) else: ref = '' if ref: branchRef = fullTreeName(currFile, ref) if branchRef in bt: print('error: Branch with name \"{0}\" already exist in current file! See node with uid=\"{1}\"' .format(ref, newNode.uid())) nodes.remove(newNode, False) return None if branchRef in project.trees: print('error: Branch with name \"{0}\" already exist in current project! See node with uid=\"{1}\"' .format(ref, newNode.uid())) nodes.remove(newNode, False) return None newNode.setRefName(ref) elif parent is None: print('error: Root nodes requires link tag \"{0}\"! Wrong node is \"{1}\" with uid=\"{2}\".' .format(cls.linkTag, name, newNode.uid())) nodes.remove(newNode, False) return None # Loading node settings:---------------------------------------------------- newNode.setParent(parent) newNode.reparseAttributes(True) # Load child nodes:--------------------------------------------------------- for chldCls in subType.children: childParams = subType.children[chldCls] childClass = project.alphabet.getClass(chldCls) if childClass is None: continue if childParams.max < 1: continue # no children of this class must be provided children = node.getElementsByTagName(childClass.tag) if diagramNode is not None: diagramChildren = diagramNode.getElementsByTagName(childClass.tag) else: diagramChildren = None loaded = 0 j = 0 for child in children: if child.parentNode is node: if diagramChildren is not None and j < len(diagramChildren) \ and diagramChildren[j].parentNode is diagramNode: childDiagramNode = diagramChildren[j] else: childDiagramNode = None childNode = self.__parseNode(version, project, bt, nodes, currFile, childClass, child, newNode, childDiagramNode) if childNode is not None: loaded += 1 newNode.addChild(childNode, silent=True) if loaded >= childParams.max: break j += 1 if loaded < childParams.min: print('warning: Node \"{0}\" with uid=\"{1}\" doesn\'t have enough \"{2}\"-children. \ Real count=\"{3}\", but must be \"{4}\".' .format(name, newNode.uid(), childClass.name, loaded, childParams.min)) # Save branch:-------------------------------------------------------------- if cls.top and newNode.refname(): if not bt.add(branch=newNode, silent=True): print('error: can\'t add node \"{0}\" with uid=\"{1}\" into trees list with branch name \"{2}\"' .format(name, newNode.uid(), newNode.refname())) nodes.remove(newNode, False) return None return newNode
def __loadTree(self, project, bt, nodes, filename): global _versionWithUids if not filename: return 0, [] filename = toUnixPath(os.path.normpath(filename)) print('info: Parsing \"{0}\" ...'.format(filename)) dom = parse(filename) data = dom.getElementsByTagName(project.alphabet.headerTree) if not data: print('error: Wrong tree file!') print('') return 0, [] mainNode = data[0] if mainNode.hasAttribute('Version'): versionText = mainNode.getAttribute('Version') elif mainNode.hasAttribute('version'): versionText = mainNode.getAttribute('version') else: versionText = '' if not versionText or '.' not in versionText: version = tuple(_versionWithUids) versionText = globals.versionToStr(version) print('info: File has no version. Default it to {0}'.format(versionText)) else: version = globals.versionFromStr(versionText) print('info: File version is {0}'.format(versionText)) # trying to read diagram file with saved diagram items positions: fname, _ = os.path.splitext(filename) diagram_file = fname + '.dgm' if os.path.exists(diagram_file): diagramData = parse(diagram_file).getElementsByTagName(project.alphabet.headerTree) if not diagramData: mainDiagramNode = None else: mainDiagramNode = diagramData[0] else: mainDiagramNode = None # getting all tags for main classes: xmlNodes = dict() topClasses = project.alphabet.getClasses(True) for t in topClasses: cls = topClasses[t] xml_nodes = mainNode.getElementsByTagName(cls.tag) if xml_nodes and cls.tag not in xmlNodes: if mainDiagramNode is not None: diagramNodes = mainDiagramNode.getElementsByTagName(cls.tag) else: diagramNodes = None xmlNodes[cls.tag] = [cls.name, xml_nodes, diagramNodes] # nodes = data[0].getElementsByTagName('Node') num_loaded = 0 if not xmlNodes: # not nodes: print('warning: Tree \"{0}\" is empty!'.format(filename)) return 0, [filename] for tag in xmlNodes: cls = project.alphabet.getClass(xmlNodes[tag][0]) xml_nodes = xmlNodes[tag][1] diagNodes = xmlNodes[tag][2] i = 0 for xml_node in xml_nodes: if xml_node.parentNode is mainNode: if diagNodes is not None and i < len(diagNodes) and diagNodes[i].parentNode is mainDiagramNode: diagramNode = diagNodes[i] else: diagramNode = None newNode = self.__parseNode(version, project, bt, nodes, filename, cls, xml_node, None, diagramNode) if newNode is not None: num_loaded += 1 i += 1 if num_loaded < 1: print('warning: no trees were loaded!') print('ok: Parsing complete.') print('') return num_loaded, [filename]
def open(self, filename): _historyBlock = _HistoryBlocker() if not filename: print('ERROR: you must specify file path to load project!') return None if not os.path.isabs(filename): filename = toUnixPath(os.path.abspath(filename)) # make full path from relative path else: filename = toUnixPath(filename) if not os.path.exists(filename): print('ERROR: file \"{0}\" does not exist!'.format(filename)) return None # create new project the_proj = Project() the_proj.path = filename # parse project file dom = parse(filename) data = dom.getElementsByTagName('btproject') if not data: print('ERROR: wrong project file! (there are no tag <btproject> in it)') return None projdata = data[0] proj_name = '' if projdata.hasAttribute('name'): proj_name = projdata.getAttribute('name') # get project name if proj_name: the_proj.name = proj_name else: the_proj.name = 'unknown project' # Loading graphic shapes file: self.__openDiagramShapes(projdata, the_proj) if the_proj.shapelib is None: print('ERROR: shape library is not specified for this project. (tag <shapelib path=\"\"/>)') return None print('OK: shape library has been loaded from \"{0}\"!'.format(the_proj.shapelib.path)) print('') # Loading alphabet file: self.__openAlphabetFile(projdata, the_proj) if the_proj.alphabet is None: print('ERROR: project requires alphabet file! (tag <alphabet path=\"\"/>)') return None libs = projdata.getElementsByTagName('library') trees = projdata.getElementsByTagName('behavior_tree') # Loading libraries: if libs: self.__openLibs(the_proj, libs) # if len(the_proj.libraries) < 1 or len(the_proj.lib_paths) < 1: # print 'WARNING: the project have no libraries! No trees will be loaded.' # return the_proj # Loading trees: if trees: self.__openTrees(the_proj, trees) if not the_proj.trees or not the_proj.tree_paths: print('WARNING: the project have no trees.') the_proj.modified = False return the_proj
def __openDiagramShapes(self, projdata, the_proj): shapes = projdata.getElementsByTagName('shapelib') if shapes and shapes[0].hasAttribute('path'): plist = self.__getPathWithCommonChecking(shapes[0], the_proj) if len(plist) == 2: the_proj.shapelib = shapelib.ShapeLib() if not the_proj.shapelib.init(plist[1]): print('warning: Can\'t load shape library from \"{0}\".'. format(plist[1])) the_proj.shapelib = None elif plist: print( 'warning: Can\'t load shape library from \"{0}\".'.format( plist[0])) else: print( 'warning: Can\'t load shape library from \"{0}\".'.format( shapes[0])) if the_proj.shapelib is None: print('info: Trying to load default diagram shapes...') try_paths = [] if isinstance(globals.applicationShapesPath, list): try_paths = globals.applicationShapesPath else: try_paths.append(globals.applicationShapesPath) okay = False err = False for path in try_paths: the_file = path if the_file is None: print( 'error: Unexpected error: empty path to diagram shapes file!' ) continue if not os.path.isabs(the_file): print( 'debug: generating absPath for \"{0}\" relative to \"{1}\"' .format(the_file, globals.rootDirectory)) the_file = absPath(the_file, globals.rootDirectory ) # make full path from relative path else: print('debug: the path \"%s\" is abs!' % the_file) the_file = toUnixPath(the_file) if the_file is None: err = True print( u'warning: Diagram shapes file \"{0}\" does not exist!' .format(path)) continue if not os.path.exists(the_file): err = True print( u'warning: Diagram shapes file \"{0}\" does not exist!' .format(the_file)) continue the_proj.shapelib = shapelib.ShapeLib() if not the_proj.shapelib.init(the_file): print('warning: Can\'t load shape library from \"{0}\".'. format(the_file)) the_proj.shapelib = None continue okay = True return
def _readConfig(args): settings = QSettings("Victor Zarubkin", "Behavior Studio") if socket.gethostname().lower() == "victor": settings.beginGroup("startup") value = settings.value("showLogo") if value is not None: value = value.lower() if value in ("true", "false"): globals.showLogo = value == "true" settings.endGroup() else: globals.showLogo = True currDir = os.getcwd() # os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # Reading application config file: configFile = None data = None try_configs = [] if isinstance(args.config_file, list): try_configs = args.config_file else: try_configs.append(args.config_file) okay = False err = False for conf in try_configs: configFile = conf data = None if not os.path.isabs(configFile): configFile = absPath(configFile, currDir) # make full path from relative path else: configFile = toUnixPath(configFile) if configFile is None: err = True print(u'warning: Config file "{0}" does not exist!'.format(conf)) continue if not os.path.exists(configFile): err = True print(u'warning: Config file "{0}" does not exist!'.format(configFile)) continue dom = parse(configFile) data = dom.getElementsByTagName("config") if not data: err = True print(u'warning: Config file "{0}" is wrong formatted! It must have header "<config>".'.format(configFile)) continue okay = True break if not okay: print("error: Can't load application configuration!") print("") return False globals.loadedApplicationConfigFile = configFile if err: print("") _readConfigIcons(configFile, data[0]) return True
def __openAlphabetFile(self, projdata, the_proj): alphs = projdata.getElementsByTagName('alphabet') if alphs and alphs[0].hasAttribute('path'): plist = self.__getPathWithCommonChecking(alphs[0], the_proj) if len(plist) == 2: the_proj.alphabet = alphabet.Alphabet() if not the_proj.alphabet.load( plist[1]) or len(the_proj.alphabet) < 1: print('warning: Can\'t load alphabet from \'{0}\'!'.format( plist[1])) print('') the_proj.alphabet = None else: print('ok: Alphabet file \'{0}\' was loaded successfully'. format(plist[1])) print('') return elif plist: print('warning: Can\'t load alphabet from \"{0}\".'.format( plist[0])) else: print('warning: Can\'t load alphabet from \"{0}\".'.format( alphs[0])) if the_proj.alphabet is None: print('info: Trying to load default behavior alphabet...') try_paths = [] if isinstance(globals.applicationAlphabetPath, list): try_paths = globals.applicationAlphabetPath else: try_paths.append(globals.applicationAlphabetPath) okay = False err = False for path in try_paths: the_file = path if not os.path.isabs(the_file): the_file = absPath(the_file, globals.rootDirectory ) # make full path from relative path else: the_file = toUnixPath(the_file) if the_file is None: err = True print(u'warning: Alphabet file \"{0}\" does not exist!'. format(path)) continue if not os.path.exists(the_file): err = True print(u'warning: Alphabet file \"{0}\" does not exist!'. format(the_file)) continue the_proj.alphabet = alphabet.Alphabet() if not the_proj.alphabet.load(the_file) or len( the_proj.alphabet) < 1: print('warning: Can\'t load alphabet from \'{0}\'!'.format( the_file)) print('') the_proj.alphabet = None continue okay = True print( 'ok: Alphabet file \'{0}\' was loaded successfully'.format( the_file)) print('') return
def main(argv): # Create a Qt application app = QApplication(argv) app.setStyle("macintosh") setPalette(app) eng_package_error_message, rus_package_error_message = _checkPackages() if eng_package_error_message or rus_package_error_message: error_message = u'<font color="red">Next python packages are required for running the program:</font><br/>' error_message += eng_package_error_message error_message += ( u'<br/><font color="yellow">---------------------------------' u"-------------------------------------------------</font><br/>" ) error_message += ( u'<font color="red">Для запуска программы необходимы следующие библиотеки для python:' u"</font><br/>" ) error_message += rus_package_error_message mb = QMessageBox(QMessageBox.Critical, "Package Error", error_message, QMessageBox.Ok) mb.exec_() sys.exit() from main_window import AppArgs, MainWindow start_path = os.environ.get("BEHAVIOR_STUDIO_ROOT", None) if start_path is None: globals.rootDirectory = os.getcwd() # globals.rootDirectory = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) else: globals.rootDirectory = start_path globals.rootDirectory = toUnixPath(os.path.normpath(globals.rootDirectory)) # Read input args appArgs = AppArgs(argv) opts = None try: opts, args = getopt.getopt(argv[1:], "hdc:", ["help", "debug", "config=", "config-file="]) except getopt.GetoptError: appArgs.options_error = True mb = QMessageBox( QMessageBox.Warning, "Options Error", '<font color="red">There are some options error!<br/>Read studio output...</font>', QMessageBox.Ok, ) mb.exec_() if not appArgs.options_error: for opt, arg in opts: if opt in ("-h", "--help"): infoString = "available options:<br/>\ -h, --help - see this hint<br/>\ -c, --config, --config-file - set start configuration file<br/>" infoString += "<br/>Example:<br/><b>{0} -c config.xml</b>".format(appArgs.current_file) mb = QMessageBox(QMessageBox.Information, "Options Help", infoString, QMessageBox.Ok) mb.exec_() sys.exit() elif opt in ("-c", "--config", "--config-file"): appArgs.config_file = arg appArgs.config_file_default = False elif opt in ("-d", "--debug"): appArgs.debug = True globals.applicationConfigFile = globals.processVars(globals.applicationConfigFile) appArgs.config_file = globals.processVars(appArgs.config_file) globals.applicationAlphabetPath = globals.processVars(globals.applicationAlphabetPath) globals.applicationShapesPath = globals.processVars(globals.applicationShapesPath) if args: appArgs.project_for_opening = toUnixPath(args[0]) if not _readConfig(appArgs): # read icons path mb = QMessageBox( QMessageBox.Critical, "Configuration Error", "Can't load application configuration!<br/>" "Configuration file <b>'{0}'</b> does not exist.".format(appArgs.config_file), QMessageBox.Ok, ) mb.exec_() sys.exit() if globals.showLogo: splash = QSplashScreen(QPixmap(joinPath(globals.applicationIconsPath, "splash2.png"))) splash.showMessage("<h2>Behavior Studio {0}</h2>".format(globals.strVersion), Qt.AlignHCenter, Qt.red) splash.show() sleep(3) else: splash = None # Create main window window = MainWindow(appArgs) window.show() if splash is not None: splash.finish(window) # window = main_window.MainStackedWindow() # window.hide() # Enter Qt application main loop app.exec_() sys.exit()
def open(self, filename): _historyBlock = _HistoryBlocker() if not filename: print('ERROR: you must specify file path to load project!') return None if not os.path.isabs(filename): filename = toUnixPath( os.path.abspath(filename)) # make full path from relative path else: filename = toUnixPath(filename) if not os.path.exists(filename): print('ERROR: file \"{0}\" does not exist!'.format(filename)) return None # create new project the_proj = Project() the_proj.path = filename # parse project file dom = parse(filename) data = dom.getElementsByTagName('btproject') if not data: print( 'ERROR: wrong project file! (there are no tag <btproject> in it)' ) return None projdata = data[0] proj_name = '' if projdata.hasAttribute('name'): proj_name = projdata.getAttribute('name') # get project name if proj_name: the_proj.name = proj_name else: the_proj.name = 'unknown project' # Loading graphic shapes file: self.__openDiagramShapes(projdata, the_proj) if the_proj.shapelib is None: print( 'ERROR: shape library is not specified for this project. (tag <shapelib path=\"\"/>)' ) return None print('OK: shape library has been loaded from \"{0}\"!'.format( the_proj.shapelib.path)) print('') # Loading alphabet file: self.__openAlphabetFile(projdata, the_proj) if the_proj.alphabet is None: print( 'ERROR: project requires alphabet file! (tag <alphabet path=\"\"/>)' ) return None libs = projdata.getElementsByTagName('library') trees = projdata.getElementsByTagName('behavior_tree') # Loading libraries: if libs: self.__openLibs(the_proj, libs) # if len(the_proj.libraries) < 1 or len(the_proj.lib_paths) < 1: # print 'WARNING: the project have no libraries! No trees will be loaded.' # return the_proj # Loading trees: if trees: self.__openTrees(the_proj, trees) if not the_proj.trees or not the_proj.tree_paths: print('WARNING: the project have no trees.') the_proj.modified = False return the_proj
def __saveNode(self, filename, xml, parentXmlNode, treeNode, diagramXml, parentDiagramXmlNode): nodeCls = treeNode.cls() # add new Node to xml curr = xml.createElement(nodeCls.tag) parentXmlNode.appendChild(curr) diagramCurr = diagramXml.createElement(nodeCls.tag) parentDiagramXmlNode.appendChild(diagramCurr) # save reference if treeNode.refname() and nodeCls.linkTag: curr.setAttribute(nodeCls.linkTag, treeNode.refname()) # save type nodeType = treeNode.type() typename = '' if nodeCls.debuggable and treeNode.debug is True: typename += 'debug ' typename += nodeType.name curr.setAttribute('Type', typename) # save unique id curr.setAttribute('uid', str(treeNode.uid())) if nodeType.isLink(): # save reference target if nodeType.linkTargetTag: strings = treeNode.target.split('/') if len(strings) > 1: targetRef = strings[-1] curr.setAttribute(nodeType.linkTargetTag, targetRef) strings.pop() targetFile = '/'.join(strings) if targetFile != filename: tfile = toUnixPath( os.path.relpath(targetFile, os.path.dirname(filename))) curr.setAttribute('File', tfile) # save diagram data self.__saveDigramData(treeNode.uid(), treeNode.diagramInfo, diagramCurr) return curr elif nodeType.singleblockEnabled and treeNode.singleBlock(): curr.setAttribute('singleBlock', '1') # save node name nodename = '' if treeNode.isInverse(): nodename += '!' nodename += treeNode.nodeName curr.setAttribute('Name', nodename) desc = treeNode.nodeDesc() if desc is not None and desc.creator: # save creator creatorName = '' if treeNode.isInverse(): creatorName += '!' creator_name = desc.creator creator_lib = '' for symbol in ('/', '|'): if symbol in desc.creator: creator_parts = desc.creator.split(symbol) creator_lib = creator_parts[0] creator_name = creator_parts[-1] if creator_lib == creator_name: creator_lib = '' break creatorName += creator_name curr.setAttribute('Creator', creatorName) if creator_lib: curr.setAttribute('CreatorLib', creator_lib) # save library curr.setAttribute(nodeCls.lib, treeNode.libname) # save attributes if nodeCls.attributes.tag: settings = xml.createElement(nodeCls.attributes.tag) curr.appendChild(settings) tags = dict() for attrName in treeNode.attributes(): attr = treeNode.attributes()[attrName] attrDesc = attr.attrDesc() if attrDesc is None: treename = treeNode.root().refname() print( 'warning: Node \'{0}\' of tree \'{1}\' has no attribute \'{2}\'. \ This attribute will not be saved.'.format( treeNode.nodeName, treename, attrName)) continue if attrDesc.isArray(): strVals = attr.valueToStr() if not strVals or not attrDesc.subtags: continue elem = settings last = len(attrDesc.subtags) - 1 for i in range(last): sub = attrDesc.subtags[i] if sub in tags: elem = tags[sub][0] continue newElem = xml.createElement(sub) tags[sub] = [newElem] elem.appendChild(newElem) elem = newElem lastSub = attrDesc.subtags[last] i = 0 for value in strVals: n = i + 1 if lastSub in tags: if len(tags[lastSub]) < n: newElem = xml.createElement(lastSub) tags[lastSub].append(newElem) elem.appendChild(newElem) curElem = newElem else: curElem = tags[lastSub][i] else: newElem = xml.createElement(lastSub) tags[lastSub] = [newElem] elem.appendChild(newElem) curElem = newElem curElem.setAttribute(attrDesc.attrname, value) i += 1 else: elem = settings for sub in attrDesc.subtags: if sub in tags: elem = tags[sub][0] continue newElem = xml.createElement(sub) tags[sub] = [newElem] elem.appendChild(newElem) elem = newElem value = attr.valueToStr() elem.setAttribute(attrDesc.attrname, value) # save diagram data self.__saveDigramData(treeNode.uid(), treeNode.diagramInfo, diagramCurr) # save children if treeNode.nodeDesc() is not None: ccc = [] for c in treeNode.allChildren(): if c in treeNode.nodeDesc().childClasses and c in nodeType: ccc.append(c) ccc.sort() for c in ccc: children = treeNode.children(c) max_children = nodeType.child(c).max num_children = 0 for child in children: if self.__saveNode(filename, xml, curr, child, diagramXml, diagramCurr) is not None: num_children += 1 if num_children >= max_children: break return curr
def __loadTree(self, project, bt, nodes, filename): global _versionWithUids if not filename: return 0, [] filename = toUnixPath(os.path.normpath(filename)) print('info: Parsing \"{0}\" ...'.format(filename)) dom = parse(filename) data = dom.getElementsByTagName(project.alphabet.headerTree) if not data: print('error: Wrong tree file!') print('') return 0, [] mainNode = data[0] if mainNode.hasAttribute('Version'): versionText = mainNode.getAttribute('Version') elif mainNode.hasAttribute('version'): versionText = mainNode.getAttribute('version') else: versionText = '' if not versionText or '.' not in versionText: version = tuple(_versionWithUids) versionText = globals.versionToStr(version) print('info: File has no version. Default it to {0}'.format( versionText)) else: version = globals.versionFromStr(versionText) print('info: File version is {0}'.format(versionText)) # trying to read diagram file with saved diagram items positions: fname, _ = os.path.splitext(filename) diagram_file = fname + '.dgm' if os.path.exists(diagram_file): diagramData = parse(diagram_file).getElementsByTagName( project.alphabet.headerTree) if not diagramData: mainDiagramNode = None else: mainDiagramNode = diagramData[0] else: mainDiagramNode = None # getting all tags for main classes: xmlNodes = dict() topClasses = project.alphabet.getClasses(True) for t in topClasses: cls = project.alphabet.getClass(t) xml_nodes = mainNode.getElementsByTagName(cls.tag) if xml_nodes and cls.tag not in xmlNodes: if mainDiagramNode is not None: diagramNodes = mainDiagramNode.getElementsByTagName( cls.tag) else: diagramNodes = None xmlNodes[cls.tag] = [cls.name, xml_nodes, diagramNodes] # nodes = data[0].getElementsByTagName('Node') num_loaded = 0 if not xmlNodes: # not nodes: print('warning: Tree \"{0}\" is empty!'.format(filename)) return 0, [filename] for tag in xmlNodes: cls = project.alphabet.getClass(xmlNodes[tag][0]) xml_nodes = xmlNodes[tag][1] diagNodes = xmlNodes[tag][2] i = 0 for xml_node in xml_nodes: if xml_node.parentNode is mainNode: if diagNodes is not None and i < len( diagNodes ) and diagNodes[i].parentNode is mainDiagramNode: diagramNode = diagNodes[i] else: diagramNode = None newNode = self.__parseNode(version, project, bt, nodes, filename, cls, xml_node, None, diagramNode) if newNode is not None: num_loaded += 1 i += 1 if num_loaded < 1: print('warning: no trees were loaded!') print('ok: Parsing complete.') print('') return num_loaded, [filename]
def __parseNode(self, version, project, bt, nodes, currFile, cls, node, parent, diagramNode): global _versionWithUids if node.hasAttribute('Name'): name = node.getAttribute('Name') else: name = '' if not name: print('ERROR: Each node requires tag \"Name\"!') return None if node.hasAttribute('Type'): nodeType = node.getAttribute('Type') else: nodeType = '' if not nodeType: print('ERROR: Each node requires tag \"Type\"!') return None strings = nodeType.split(' ') nodeType = strings[-1] if nodeType not in cls: print('error: Type \"{0}\" is not specified for class \"{1}\".'. format(nodeType, cls.name)) return None # read diagram info: diagramInfo, diagramUid = self.__readDiagramInfo(diagramNode) isInverse = False if '!' in name or '~' in name: isInverse = True name = name.replace('!', '') name = name.replace('~', '') name = name.strip() # Checking for debug usage: isDebug = False if len(strings ) > 1 and cls.debuggable and strings[0] in self.__debug_str: isDebug = True # Checking for single-block: isSingleBlock = False if node.hasAttribute('singleBlock'): sb = node.getAttribute('singleBlock').lower() if sb not in ('0', 'no', 'false'): isSingleBlock = True # Getting uid for node: if node.hasAttribute('uid'): u = node.getAttribute('uid') if u: uid = int(u) else: uid = None else: uid = None subType = cls.get(nodeType) if subType.isLink(): isSingleBlock = False target = '' if node.hasAttribute(subType.targetTag()): target = node.getAttribute(subType.targetTag()) if not target: print( 'error: All links must have target! (tag <{0}> is missing)' .format(subType.targetTag())) return None filename = '' if node.hasAttribute('File'): filename = node.getAttribute('File') if not os.path.isabs(filename): realpath = '/'.join([os.path.dirname(currFile), filename]) filename = os.path.normpath(os.path.abspath(realpath)) filename = toUnixPath(filename) if not os.path.exists(filename): filename = '' if not filename: filename = currFile branchRef = fullTreeName(filename, target) if branchRef in bt or branchRef in project.trees: newNode = treenode.TreeNode(project, node, cls.name, nodeType, isDebug, uid) newNode.target = branchRef newNode.setPath(currFile) if diagramUid == newNode.uid() or version < _versionWithUids: newNode.diagramInfo = diagramInfo if newNode.uid() in nodes: print( 'error: Node with uid \"{0}\" already exist in current file!' .format(newNode.uid())) return None if newNode.uid() in project.nodes: print( 'error: Node with uid \"{0}\" already exist in current project!' .format(newNode.uid())) return None nodes.add(newNode, False) return newNode print( 'error: Link to \"{0}\" is not found neither in file \"{1}\" nor in current project!' .format(target, filename)) return None elif not subType.singleblockEnabled: isSingleBlock = False if node.hasAttribute(cls.lib): libname = node.getAttribute(cls.lib) else: libname = '' if not libname: print('error: Each \"{0}\" node requires tag \"{1}\"!'.format( cls.name, cls.lib)) return None newNode = treenode.TreeNode(project, node, cls.name, nodeType, isDebug, uid) if newNode.uid() in nodes: print( 'error: Node with uid \"{0}\" already exist in current file!'. format(newNode.uid())) return None if newNode.uid() in project.nodes: print( 'error: Node with uid \"{0}\" already exist in current project!' .format(newNode.uid())) return None nodes.add(newNode, False) newNode.setSingleblock(isSingleBlock) newNode.setLibName(libname) newNode.setNodeName(name) newNode.setPath(currFile) if diagramUid == newNode.uid() or version < _versionWithUids: newNode.diagramInfo = diagramInfo if isInverse: newNode.setInverse(isInverse) # Read branch name:-------------------------------------------------------------- if cls.top: if node.hasAttribute(cls.linkTag): ref = node.getAttribute(cls.linkTag) else: ref = '' if ref: branchRef = fullTreeName(currFile, ref) if branchRef in bt: print( 'error: Branch with name \"{0}\" already exist in current file! See node with uid=\"{1}\"' .format(ref, newNode.uid())) nodes.remove(newNode, False) return None if branchRef in project.trees: print( 'error: Branch with name \"{0}\" already exist in current project! See node with uid=\"{1}\"' .format(ref, newNode.uid())) nodes.remove(newNode, False) return None newNode.setRefName(ref) elif parent is None: print( 'error: Root nodes requires link tag \"{0}\"! Wrong node is \"{1}\" with uid=\"{2}\".' .format(cls.linkTag, name, newNode.uid())) nodes.remove(newNode, False) return None # Loading node settings:---------------------------------------------------- newNode.setParent(parent) newNode.reparseAttributes(True) # Load child nodes:--------------------------------------------------------- for chldCls in subType.children: childParams = subType.children[chldCls] childClass = project.alphabet.getClass(chldCls) if childClass is None: continue if childParams.max < 1: continue # no children of this class must be provided children = node.getElementsByTagName(childClass.tag) if diagramNode is not None: diagramChildren = diagramNode.getElementsByTagName( childClass.tag) else: diagramChildren = None loaded = 0 j = 0 for child in children: if child.parentNode is node: if diagramChildren is not None and j < len(diagramChildren) \ and diagramChildren[j].parentNode is diagramNode: childDiagramNode = diagramChildren[j] else: childDiagramNode = None childNode = self.__parseNode(version, project, bt, nodes, currFile, childClass, child, newNode, childDiagramNode) if childNode is not None: loaded += 1 newNode.addChild(childNode, silent=True) if loaded >= childParams.max: break j += 1 if loaded < childParams.min: print( 'warning: Node \"{0}\" with uid=\"{1}\" doesn\'t have enough \"{2}\"-children. \ Real count=\"{3}\", but must be \"{4}\".'.format( name, newNode.uid(), childClass.name, loaded, childParams.min)) # Save branch:-------------------------------------------------------------- if cls.top and newNode.refname(): if not bt.add(branch=newNode, silent=True): print( 'error: can\'t add node \"{0}\" with uid=\"{1}\" into trees list with branch name \"{2}\"' .format(name, newNode.uid(), newNode.refname())) nodes.remove(newNode, False) return None return newNode