def __init__(self, initDict=None, setDefaults=False): if not initDict: initDict = {} dict.__init__(self, initDict) self.derivedDict = {} self.hasConditionals = False if setDefaults: self[TreeFormats.rootFormatDefault] = \ nodeformat.NodeFormat(TreeFormats.rootFormatDefault, {}, TreeFormats.fieldDefault) self[TreeFormats.formatDefault] = \ nodeformat.NodeFormat(TreeFormats.formatDefault, {}, TreeFormats.fieldDefault) self[TreeFormats.rootFormatDefault].childType = \ TreeFormats.formatDefault
def loadL5XNode(self, element, model, parent=None): """Recursively load a generic XML ElementTree node and its children. Arguments: element -- an XML ElementTree node model -- a ref to the TreeLine model parent -- the parent TreeNode (None for the root node only) """ elemFormat = model.formats.get(element.tag, None) if not elemFormat: elemFormat = nodeformat.NodeFormat(element.tag, model.formats) model.formats[element.tag] = elemFormat node = treenode.TreeNode(parent, elemFormat.name, model) if parent: parent.childList.append(node) elif model.root: raise ElementTree.ParseError # invalid with two roots else: model.root = node if element.text and element.text.strip(): if genericXmlTextFieldName not in elemFormat.fieldDict: elemFormat.addFieldList([genericXmlTextFieldName], True, True) node.setTitle(element.text.strip()) for key, value in element.items(): elemFormat.addFieldIfNew(key) node.data[key] = value for child in element: self.loadL5XNode(child, model, node)
def loadXmlNode(self, element, structure, parent=None): """Recursively load a generic XML ElementTree node and its children. Arguments: element -- an XML ElementTree node structure -- a ref to the TreeLine structure parent -- the parent TreeNode (None for the root node only) """ elemFormat = structure.treeFormats.get(element.tag, None) if not elemFormat: elemFormat = nodeformat.NodeFormat(element.tag, structure.treeFormats) structure.treeFormats[element.tag] = elemFormat node = treenode.TreeNode(elemFormat) structure.addNodeDictRef(node) if not parent: parent = structure parent.childList.append(node) if element.text and element.text.strip(): if genericXmlTextFieldName not in elemFormat.fieldDict: elemFormat.addFieldList([genericXmlTextFieldName], True, True) node.setTitle(element.text.strip()) for key, value in element.items(): elemFormat.addFieldIfNew(key) node.data[key] = value for child in element: self.loadXmlNode(child, structure, node)
def __init__(self, setDefault=False): """Initialize the format storage. Arguments: setDefault - if true, initializes with a default format """ super().__init__() # new names for types renamed in the config dialog (orig names as keys) self.typeRenameDict = {} # nested dict for fields renamed, keys are type name then orig field self.fieldRenameDict = {} # list of format types with unique ID ref field changes self.changedIdFieldTypes = set() # set of math field names with deleted equations, keys are type names self.emptiedMathDict = {} self.conditionalTypes = set() self.mathFieldRefDict = {} # list of math eval levels, each is a dict by type name with lists of # equation fields self.mathLevelList = [] # for saving all-type find/filter conditionals self.savedConditionText = {} self.configModified = False self.fileInfoFormat = nodeformat.FileInfoFormat(self) if setDefault: self[defaultTypeName] = nodeformat.NodeFormat(defaultTypeName, self, {}, True) self.updateLineParsing()
def importTableTabbed(self): """Import a file with a tab-delimited table with header row. Return the structure if import is successful, otherwise None. """ structure = treestructure.TreeStructure(addDefaults=True, addSpots=False) tableFormat = nodeformat.NodeFormat(_('TABLE'), structure.treeFormats) structure.treeFormats.addTypeIfMissing(tableFormat) with self.pathObj.open(encoding=globalref.localTextEncoding) as f: headings = [ self.correctFieldName(name) for name in f.readline().split('\t') ] tableFormat.addFieldList(headings, True, True) lineNum = 1 for line in f: lineNum += 1 if line.strip(): entries = line.split('\t') node = treenode.TreeNode(tableFormat) structure.childList[0].childList.append(node) structure.addNodeDictRef(node) try: for heading in headings: node.data[heading] = entries.pop(0) except IndexError: pass # fewer entries than headings is OK if entries: self.errorMessage = ( _('Too many entries on Line {0}').format(lineNum)) return None # abort if too few headings structure.generateSpots(None) return structure
def exportTrlSubtree(self, fileRef, nodeList, addBranches=True): """Write subtree TRL file starting form item""" lines = [u'<?xml version="1.0" encoding="utf-8" ?>'] if self.xlstLink: lines.append(u'<?%s?>' % self.xlstLink) if not addBranches: newList = [] for item in nodeList: # replace items with childless items newItem = TreeItem(item.parent, item.formatName) newItem.data = item.data newList.append(newItem) nodeList = newList if len(nodeList) > 1: format = nodeformat.NodeFormat(TreeFormats.rootFormatDefault, {}, TreeFormats.fieldDefault) self.treeFormats.addIfMissing(format) item = TreeItem(None, format.name) item.data[TreeFormats.fieldDefault] = TreeDoc.rootTitleDefault for child in nodeList: item.childList.append(child) child.parent = item else: item = nodeList[0] lines.extend(item.branchXml([], True)) try: f = self.getWriteFileObj(fileRef, self.compressFile) f.writelines([(line + '\n').encode('utf-8') for line in lines]) except IOError: print 'Error - could not write file' self.treeFormats.removeQuiet(TreeDoc.copyFormat) raise f.close() self.treeFormats.removeQuiet(TreeDoc.copyFormat)
def importTableText(self): """Import a file with a tab-delimited table with header row. Return the model if import is successful, otherwise None. """ model = treemodel.TreeModel(True) typeName = _('TABLE') tableFormat = nodeformat.NodeFormat(typeName, model.formats) model.formats.addTypeIfMissing(tableFormat) with open(self.filePath, 'r', encoding=globalref.localTextEncoding) as f: headings = [ self.correctFieldName(name) for name in f.readline().split('\t') ] tableFormat.addFieldList(headings, True, True) lineNum = 1 for line in f: lineNum += 1 if line.strip(): entries = line.split('\t') node = treenode.TreeNode(model.root, typeName, model) model.root.childList.append(node) try: for heading in headings: node.data[heading] = entries.pop(0) except IndexError: pass # fewer entries than headings is OK if entries: self.errorMessage = ( _('Too many entries on Line {0}').format(lineNum)) return None # abort if too few headings node.setUniqueId(True) return model
def addChildCat(self, catList): """Add child's category items as a new child level to expand data""" catSuffix = _('TYPE', 'child category suffix') newType = u'%s_%s' % (catList[0], catSuffix) num = 1 while newType in globalref.docRef.treeFormats and \ globalref.docRef.treeFormats[newType].fieldNames() != catList: newType = u'%s_%s_%d' % (catList[0], catSuffix, num) num += 1 newFormat = nodeformat.NodeFormat(newType, {}, catList[0]) globalref.docRef.treeFormats[newType] = newFormat for field in catList[1:]: newFormat.addNewField(field) newItems = [] for child in self.childList: newParent = child.findEquivFields(catList, newItems) if not newParent: newParent = TreeItem(self, newType) newParent.setUniqueID(True) for field in catList: newParent.data[field] = child.data.get(field, '') newItems.append(newParent) newParent.childList.append(child) child.parent = newParent self.childList = newItems globalref.docRef.modified = True
def addDummyRootType(self): """Add temporary dummy root format and return it. Used as a root item for copying a multiple selection. """ typeFormat = nodeformat.NodeFormat(dummyRootTypeName, self) self[dummyRootTypeName] = typeFormat return typeFormat
def loadOldTreeLineNode(self, element, structure, idRefDict, linkList, parent=None): """Recursively load an old TreeLine ElementTree node and its children. Arguments: element -- an ElementTree node structure -- a ref to the new tree structure idRefDict -- a dict to relate old to new unique node IDs linkList -- internal link list ref with (node, fieldname) tuples parent -- the parent TreeNode (None for the root node only) """ try: typeFormat = structure.treeFormats[element.tag] except KeyError: formatData = self.convertOldNodeFormat(element.attrib) typeFormat = nodeformat.NodeFormat(element.tag, structure.treeFormats, formatData) structure.treeFormats[element.tag] = typeFormat self.treeLineOldFieldAttr[typeFormat.name] = {} if element.get('item') == 'y': node = treenode.TreeNode(typeFormat) oldId = element.attrib.get('uniqueid', '') if oldId: idRefDict[oldId] = node.uId if parent: parent.childList.append(node) else: structure.childList.append(node) structure.nodeDict[node.uId] = node cloneAttr = element.attrib.get('clones', '') if cloneAttr: for cloneId in cloneAttr.split(','): if cloneId in idRefDict: cloneNode = structure.nodeDict[idRefDict[cloneId]] node.data = cloneNode.data.copy() break else: # bare format (no nodes) node = None for child in element: if child.get('item') and node: self.loadOldTreeLineNode(child, structure, idRefDict, linkList, node) else: if node and child.text: node.data[child.tag] = child.text if child.get('linkcount'): linkList.append((node, child.tag)) if child.tag not in typeFormat.fieldDict: fieldData = self.convertOldFieldFormat(child.attrib) oldFormatDict = self.treeLineOldFieldAttr[typeFormat.name] oldFormatDict[child.tag] = fieldData typeFormat.addField(child.tag, fieldData)
def readTreepad(self, fileRef, errors='strict'): """Read Treepad text-node file""" try: f = self.getEncodedFileObj(fileRef, globalref.localTextEncoding, errors) filePath = unicode(f.name, sys.getfilesystemencoding()) textList = f.read().split('<end node> 5P9i0s8y19Z') f.close() except UnicodeError: # error common - broken unicode on windows print 'Warning - bad unicode characters were replaced' if errors == 'strict': self.readTreepad(fileRef, 'replace') else: f.close() return self.treeFormats = TreeFormats() format = nodeformat.NodeFormat(TreeFormats.formatDefault) titleFieldName = _('Title', 'title field name') format.addNewField(titleFieldName) format.addLine(u'{*%s*}' % titleFieldName) numLines = globalref.options.intData('MaxEditLines', 1, optiondefaults.maxNumLines) format.addNewField(TreeFormats.textFieldName, {'lines': repr(numLines)}) format.addLine(u'{*%s*}' % TreeFormats.textFieldName) self.treeFormats[format.name] = format itemList = [] for text in textList: text = text.strip() if text: try: text = text.split('<node>', 1)[1].lstrip() lines = text.split('\n') title = lines[0] level = int(lines[1]) lines = lines[2:] except (ValueError, IndexError): print 'Error - bad file format in %s' % \ filePath.encode(globalref.localTextEncoding) raise ReadFileError(_('Bad file format in %s') % filePath) item = TreeItem(None, format.name) item.data[titleFieldName] = title item.data[TreeFormats.textFieldName] = '\n'.join(lines) item.level = level itemList.append(item) self.root = itemList[0] parentList = [] for item in itemList: if item.level != 0: parentList = parentList[:item.level] item.parent = parentList[-1] parentList[-1].childList.append(item) parentList.append(item) self.root = itemList[0] self.fileName = filePath
def __init__(self, formatList=None, setDefault=False): """Initialize the format storage. Arguments: formatList -- the list of formats' file info setDefault - if true, initializes with a default format """ super().__init__() # new names for types renamed in the config dialog (orig names as keys) self.typeRenameDict = {} # nested dict for fields renamed, keys are type name then orig field self.fieldRenameDict = {} self.conditionalTypes = set() # set of math field names with deleted equations, keys are type names self.emptiedMathDict = {} self.mathFieldRefDict = {} # list of math eval levels, each is a dict by type name with lists of # equation fields self.mathLevelList = [] # for saving all-type find/filter conditionals self.savedConditionText = {} self.fileInfoFormat = nodeformat.FileInfoFormat(self) if formatList: for formatData in formatList: name = formatData['formatname'] self[name] = nodeformat.NodeFormat(name, self, formatData) self.updateDerivedRefs() try: self.updateMathFieldRefs() except matheval.CircularMathError: # can see if types with math fields were copied from a 2nd file # handle the exception to avoid failure at file open print('Warning - Circular math fields detected') if nodeformat.FileInfoFormat.typeName in self: self.fileInfoFormat.duplicateFileInfo( self[nodeformat.FileInfoFormat.typeName]) del self[nodeformat.FileInfoFormat.typeName] if setDefault: self[defaultTypeName] = nodeformat.NodeFormat(defaultTypeName, self, addDefaultField=True)
def createBookmarkFormat(self): """Return a set of formats for bookmark imports""" treeFormats = TreeFormats() format = nodeformat.NodeFormat(TreeDoc.folderName) format.addNewField(TreeFormats.fieldDefault) format.addLine(u'{*%s*}' % TreeFormats.fieldDefault) format.addLine(u'{*%s*}' % TreeFormats.fieldDefault) format.iconName = 'folder_3' treeFormats[format.name] = format format = nodeformat.NodeFormat(TreeDoc.bookmarkName) format.addNewField(TreeFormats.fieldDefault) format.addLine(u'{*%s*}' % TreeFormats.fieldDefault) format.addLine(u'{*%s*}' % TreeFormats.fieldDefault) format.addNewField(TreeFormats.linkFieldName, {'type': 'URL'}) format.addLine(u'{*%s*}' % TreeFormats.linkFieldName) format.iconName = 'bookmark' treeFormats[format.name] = format format = nodeformat.NodeFormat(TreeDoc.separatorName) format.addNewField(TreeFormats.fieldDefault) format.addLine(u'------------------') format.addLine(u'<hr>') treeFormats[format.name] = format return treeFormats
def createBookmarkFormat(self): """Return a set of node formats for bookmark imports. """ treeFormats = treeformats.TreeFormats() folderFormat = nodeformat.NodeFormat(bookmarkFolderTypeName, treeFormats, addDefaultField=True) folderFormat.iconName = 'folder_3' treeFormats[folderFormat.name] = folderFormat linkFormat = nodeformat.NodeFormat(bookmarkLinkTypeName, treeFormats, addDefaultField=True) linkFormat.addField(bookmarkLinkFieldName, {'type': 'ExternalLink'}) linkFormat.addOutputLine('{{*{0}*}}'.format(bookmarkLinkFieldName)) linkFormat.iconName = 'bookmark' treeFormats[linkFormat.name] = linkFormat sepFormat = nodeformat.NodeFormat(bookmarkSeparatorTypeName, treeFormats, {'formathtml': 'y'}, True) sepFormat.changeTitleLine('------------------') sepFormat.changeOutputLines(['<hr>']) treeFormats[sepFormat.name] = sepFormat return treeFormats
def importTableCsvLevels(self): """Import a CSV-delimited table file with level column, header row. Return the structure if import is successful, otherwise None. """ structure = treestructure.TreeStructure(addSpots=False) tableFormat = nodeformat.NodeFormat(_('TABLE'), structure.treeFormats) structure.treeFormats.addTypeIfMissing(tableFormat) nodeList = [] with self.pathObj.open(newline='', encoding=globalref.localTextEncoding) as f: reader = csv.reader(f) try: headings = [ self.correctFieldName(name) for name in next(reader) ][1:] tableFormat.addFieldList(headings, True, True) for entries in reader: if entries: node = treenode.TreeNode(tableFormat) structure.addNodeDictRef(node) try: level = int(entries.pop(0)) except ValueError: self.errorMessage = (_('Invalid level number on ' 'line {0}').format( reader.line_num)) return None # abort nodeList.append((node, level)) try: for heading in headings: node.data[heading] = entries.pop(0) except IndexError: pass # fewer entries than headings is OK if entries: self.errorMessage = (_('Too many entries on ' 'Line {0}').format( reader.line_num)) return None # abort if too few headings except csv.Error: self.errorMessage = (_('Bad CSV format on Line {0}').format( reader.line_num)) return None # abort if nodeList: if structure.loadChildNodeLevels(nodeList): structure.generateSpots(None) return structure self.errorMessage = (_('Invalid level structure')) return None
def startElement(self, name, attrs): """Called by the reader at the open tag of each element""" format = self.formats.get(name, None) if not format: format = nodeformat.NodeFormat(name) self.formats[name] = format newItem = TreeItem(self.currentItem, name) if self.currentItem: self.currentItem.childList.append(newItem) elif self.rootItem: raise xml.sax.SAXException, 'Invalid XML file' else: self.rootItem = newItem self.currentItem = newItem for key in attrs.keys(): format.addFieldIfNew(key) newItem.data[key] = attrs[key]
def newNodeFormat(self, formatName, defaultFieldName='Name'): """Create a new node format and add it to the available tree formats. The format name must only contain characters [a-zA-Z0-9_.-]. If defaultFieldName, a text field is created and added to the title line and the first output line. Arguments: formatName -- the new format name defaultFieldName -- if defined, a text field is created and added """ treeFormats = globalref.mainControl.activeControl.model.formats newFormat = nodeformat.NodeFormat(formatName, treeFormats) if defaultFieldName: newFormat.addFieldIfNew(defaultFieldName) newFormat.lineList = ['{{*{0}*}}'.format(defaultFieldName)] * 2 newFormat.updateLineParsing() treeFormats[formatName] = newFormat
def startElement(self, name, attrs): """Called by the reader at the open tag of each element""" if attrs.get(u'item', ''): # reading TreeItem or bare format format = self.formats.get(name, None) if not format: format = nodeformat.NodeFormat(name, attrs) self.formats[name] = format if attrs.get(u'item', '') == 'y': # reading TreeItem newItem = TreeItem(self.currentItem, name) if self.currentItem: self.currentItem.childList.append(newItem) else: self.rootItem = newItem if attrs.get(u'nospace', '').startswith('y'): self.docRef.spaceBetween = False if attrs.get(u'nobreaks', '').startswith('y'): self.docRef.lineBreaks = False if attrs.get(u'nohtml', '').startswith('y'): self.docRef.formHtml = False if attrs.get(u'childsep', ''): self.docRef.childFieldSep = attrs.get(u'childsep', '') self.docRef.spellChkLang = attrs.get(u'spellchk', '') self.docRef.xslCssLink = attrs.get(u'xslcss', '') self.docRef.tlVersion = attrs.get(u'tlversion', '') self.currentItem = newItem else: # reading bare format self.bareFormat = format else: # reading data self.text = '' self.dataEntry = name if not self.currentItem: raise xml.sax.SAXException, 'No valid item' currentFormat = self.bareFormat if not currentFormat: try: currentFormat = self.formats[self.currentItem.formatName] except KeyError: raise xml.sax.SAXException, 'Invalid node type' if name not in currentFormat.fieldNames( ): # add new field to format try: currentFormat.addNewField(name, attrs) except (NameError, KeyError): raise xml.sax.SAXException, 'Invalid field type'
def addChildCategory(self, catList, structure): """Insert category nodes above children. Arguments: catList -- the field names to add to the new level structure -- a ref to the tree structure """ newFormat = None catSet = set(catList) similarFormats = [ nodeFormat for nodeFormat in structure.treeFormats.values() if catSet.issubset(set(nodeFormat.fieldNames())) ] if similarFormats: similarFormat = min(similarFormats, key=lambda f: len(f.fieldDict)) if len(similarFormat.fieldDict) < len( self.childList[0].formatRef.fieldDict): newFormat = similarFormat if not newFormat: newFormatName = '{0}_TYPE'.format(catList[0].upper()) num = 1 while newFormatName in structure.treeFormats: newFormatName = '{0}_TYPE_{1}'.format(catList[0].upper(), num) num += 1 newFormat = nodeformat.NodeFormat(newFormatName, structure.treeFormats) newFormat.addFieldList(catList, True, True) structure.treeFormats[newFormatName] = newFormat newParents = [] for child in self.childList: newParent = child.findEqualFields(catList, newParents) if not newParent: newParent = TreeNode(newFormat) for field in catList: data = child.data.get(field, '') if data: newParent.data[field] = data structure.addNodeDictRef(newParent) newParents.append(newParent) newParent.childList.append(child) self.childList = newParents for child in self.childList: child.removeInvalidSpotRefs(True, True) child.addSpotRef(self)
def __init__(self, filePath=None, setNewDefaults=False, importType=None): """Open filePath (can also be file ref) if given, setNewDefaults uses user defaults for compression & encryption, importType gives an import method to read the file""" globalref.docRef = self self.root = None self.treeFormats = TreeFormats() self.fileInfoItem = TreeItem(None, nodeformat.FileInfoFormat.name) self.fileInfoFormat = None TreeDoc.copyFormat = nodeformat.NodeFormat('_DUMMY__ROOT_', {}, TreeFormats.fieldDefault) self.undoStore = undo.UndoRedoStore() self.redoStore = undo.UndoRedoStore() self.sortFields = [''] self.fileName = '' self.spaceBetween = True self.lineBreaks = True self.formHtml = True self.childFieldSep = TreeDoc.childFieldSepDflt self.spellChkLang = '' self.xlstLink = '' self.xslCssLink = '' self.tlVersion = __version__ self.fileInfoFormat = nodeformat.FileInfoFormat() if filePath: if importType: getattr(self, importType)(filePath) else: self.readFile(filePath) else: self.treeFormats = TreeFormats({}, True) self.root = TreeItem(None, TreeFormats.rootFormatDefault) self.root.setTitle(TreeDoc.rootTitleDefault) self.modified = False if setNewDefaults or not hasattr(self, 'compressFile'): self.compressFile = globalref.options.boolData('CompressNewFiles') self.encryptFile = globalref.options.boolData('EncryptNewFiles') elif not hasattr(self, 'encryptFile'): self.encryptFile = False self.selection = treeselection.TreeSelection([self.root]) self.fileInfoFormat.translateFields() self.fileInfoFormat.updateFileInfo()
def loadNode(self, element, parent=None): """Recursively load an ElementTree node and its children. Arguments: element -- an ElementTree node parent -- the parent TreeNode (None for the root node only) """ try: typeFormat = self.model.formats[element.tag] except KeyError: typeFormat = nodeformat.NodeFormat(element.tag, self.model.formats, element.attrib) self.model.formats[element.tag] = typeFormat if element.get('item') == 'y': node = treenode.TreeNode(parent, element.tag, self.model, element.attrib) if parent: parent.childList.append(node) else: self.model.root = node else: # bare format (no nodes) node = None for child in element: if child.get('item') and node: self.loadNode(child, node) else: if node and child.text: node.data[child.tag] = child.text if child.get('linkcount'): self.model.linkRefCollect.searchForLinks(node, child.tag) typeFormat.addFieldIfNew(child.tag, child.attrib) if node and typeFormat.fieldDict: try: node.setUniqueId() except ValueError: oldId = node.uniqueId node.setUniqueId(True) self.duplicateIdList.append('{0} -> {1}'.format(oldId, node.uniqueId))
def importTableCsv(self): """Import a file with a CSV-delimited table with header row. Return the structure if import is successful, otherwise None. """ structure = treestructure.TreeStructure(addDefaults=True, addSpots=False) tableFormat = nodeformat.NodeFormat(_('TABLE'), structure.treeFormats) structure.treeFormats.addTypeIfMissing(tableFormat) with self.pathObj.open(newline='', encoding=globalref.localTextEncoding) as f: reader = csv.reader(f) try: headings = [ self.correctFieldName(name) for name in next(reader) ] tableFormat.addFieldList(headings, True, True) for entries in reader: if entries: node = treenode.TreeNode(tableFormat) structure.childList[0].childList.append(node) structure.addNodeDictRef(node) try: for heading in headings: node.data[heading] = entries.pop(0) except IndexError: pass # fewer entries than headings is OK if entries: self.errorMessage = (_('Too many entries on ' 'Line {0}').format( reader.line_num)) return None # abort if too few headings except csv.Error: self.errorMessage = (_('Bad CSV format on Line {0}').format( reader.line_num)) return None # abort structure.generateSpots(None) return structure
def newNodeFormat(self, formatName, defaultFieldName='Name'): """Create a new node format, names must only contain characters [a-zA-Z0-9_.-]. If defaultFieldName, a text field is created and added to the title line and the first output line""" format = nodeformat.NodeFormat(formatName, {}, defaultFieldName) globalref.docRef.treeFormats[formatName] = format
def visualConfigStructure(self, fileName): """Export a TreeLine structure containing the config types and fields. Returns the structure. Arguments: fileName -- the name for the root node """ structure = treestructure.TreeStructure() structure.treeFormats = TreeFormats() rootFormat = nodeformat.NodeFormat(_showConfRootTypeName, structure.treeFormats, addDefaultField=True) structure.treeFormats[rootFormat.name] = rootFormat typeFormat = nodeformat.NodeFormat(_showConfTypeTypeName, structure.treeFormats, addDefaultField=True) typeFormat.addField(_showConfTypeTitleFieldName) typeFormat.addField(_showConfTypeOutputFieldName) typeFormat.addField(_showConfTypeSpaceFieldName, {'fieldtype': 'Boolean'}) typeFormat.addField(_showConfTypeHtmlFieldName, {'fieldtype': 'Boolean'}) typeFormat.addField(_showConfTypeBulletsFieldName, {'fieldtype': 'Boolean'}) typeFormat.addField(_showConfTypeTableFieldName, {'fieldtype': 'Boolean'}) typeFormat.addField(_showConfTypeChildFieldName) typeFormat.addField(_showConfTypeIconFieldName) typeFormat.addField(_showConfTypeGenericFieldName) typeFormat.addField(_showConfTypeConditionFieldName) typeFormat.addField(_showConfTypeSeparatorFieldName) typeFormat.addField(_showConfTypeChildLimitFieldName) structure.treeFormats[typeFormat.name] = typeFormat fieldFormat = nodeformat.NodeFormat(_showConfFieldTypeName, structure.treeFormats, addDefaultField=True) fieldFormat.addField(_showConfFieldTypeFieldName) fieldFormat.addField(_showConfFieldFormatFieldName) fieldFormat.addField(_showConfFieldPrefixFieldName) fieldFormat.addField(_showConfFieldSuffixFieldName) fieldFormat.addField(_showConfFieldInitFieldName) fieldFormat.addField(_showConfFieldLinesFieldName, {'fieldtype': 'Number'}) fieldFormat.addField(_showConfFieldSortKeyFieldName, {'fieldtype': 'Number'}) fieldFormat.addField(_showConfFieldSortDirFieldName, {'fieldtype': 'Boolean'}) fieldFormat.addField(_showConfFieldEvalHtmlFieldName, {'fieldtype': 'Boolean'}) line = '{{*{0}*}} ({{*{1}*}})'.format(nodeformat.defaultFieldName, _showConfFieldTypeFieldName) fieldFormat.changeTitleLine(line) fieldFormat.changeOutputLines([line]) structure.treeFormats[fieldFormat.name] = fieldFormat rootNode = treenode.TreeNode(rootFormat) structure.childList.append(rootNode) structure.addNodeDictRef(rootNode) rootNode.data[nodeformat.defaultFieldName] = fileName for typeName in self.typeNames(): typeNode = treenode.TreeNode(typeFormat) rootNode.childList.append(typeNode) structure.addNodeDictRef(typeNode) typeNode.data[nodeformat.defaultFieldName] = typeName titleLine = self[typeName].getTitleLine() outputList = self[typeName].getOutputLines() if self[typeName].formatHtml: titleLine = xml.sax.saxutils.escape(titleLine) outputList = [ xml.sax.saxutils.escape(line) for line in outputList ] outputLines = '<br>\n'.join(outputList) typeNode.data[_showConfTypeTitleFieldName] = titleLine typeNode.data[_showConfTypeOutputFieldName] = outputLines spaceBetween = repr(self[typeName].spaceBetween) typeNode.data[_showConfTypeSpaceFieldName] = spaceBetween formatHtml = repr(self[typeName].formatHtml) typeNode.data[_showConfTypeHtmlFieldName] = formatHtml useBullets = repr(self[typeName].useBullets) typeNode.data[_showConfTypeBulletsFieldName] = useBullets useTables = repr(self[typeName].useTables) typeNode.data[_showConfTypeTableFieldName] = useTables typeNode.data[_showConfTypeChildFieldName] = ( self[typeName].childType) typeNode.data[_showConfTypeIconFieldName] = ( self[typeName].iconName) typeNode.data[_showConfTypeGenericFieldName] = ( self[typeName].genericType) if self[typeName].conditional: condition = self[typeName].conditional.conditionStr() typeNode.data[_showConfTypeConditionFieldName] = condition separator = self[typeName].outputSeparator typeNode.data[_showConfTypeSeparatorFieldName] = separator childLimit = ','.join(sorted(list(self[typeName].childTypeLimit))) typeNode.data[_showConfTypeChildLimitFieldName] = childLimit fieldSortKeyDict = {} fieldSortSet = False for field in self[typeName].fields(): fieldSortKeyDict[field.name] = repr(field.sortKeyNum) if field.sortKeyNum != 0: fieldSortSet = True if not fieldSortSet: sortField = list(self[typeName].fields())[0] fieldSortKeyDict[sortField.name] = repr(1) for field in self[typeName].fields(): fieldNode = treenode.TreeNode(fieldFormat) typeNode.childList.append(fieldNode) structure.addNodeDictRef(fieldNode) fieldNode.data[nodeformat.defaultFieldName] = field.name fieldNode.data[_showConfFieldTypeFieldName] = field.typeName fieldNode.data[_showConfFieldFormatFieldName] = field.format fieldNode.data[_showConfFieldPrefixFieldName] = field.prefix fieldNode.data[_showConfFieldSuffixFieldName] = field.suffix fieldNode.data[_showConfFieldInitFieldName] = field.initDefault numLines = repr(field.numLines) fieldNode.data[_showConfFieldLinesFieldName] = numLines sortKeyNum = fieldSortKeyDict[field.name] fieldNode.data[_showConfFieldSortKeyFieldName] = sortKeyNum sortKeyFwd = repr(field.sortKeyForward) fieldNode.data[_showConfFieldSortDirFieldName] = sortKeyFwd evalHtml = repr(field.evalHtml) fieldNode.data[_showConfFieldEvalHtmlFieldName] = evalHtml structure.generateSpots(None) return structure