コード例 #1
0
 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
コード例 #2
0
ファイル: imports.py プロジェクト: isoftpk/gmedit
    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)
コード例 #3
0
    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)
コード例 #4
0
ファイル: treeformats.py プロジェクト: isoftpk/gmedit
    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()
コード例 #5
0
    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
コード例 #6
0
ファイル: treedoc.py プロジェクト: rodolfoap/treeline141
 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)
コード例 #7
0
ファイル: imports.py プロジェクト: isoftpk/gmedit
    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
コード例 #8
0
 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
コード例 #9
0
ファイル: treeformats.py プロジェクト: isoftpk/gmedit
    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
コード例 #10
0
    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)
コード例 #11
0
ファイル: treedoc.py プロジェクト: rodolfoap/treeline141
 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
コード例 #12
0
    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)
コード例 #13
0
ファイル: treedoc.py プロジェクト: rodolfoap/treeline141
 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
コード例 #14
0
ファイル: imports.py プロジェクト: isoftpk/gmedit
 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
コード例 #15
0
    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
コード例 #16
0
ファイル: treexmlparse.py プロジェクト: rodolfoap/treeline141
 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]
コード例 #17
0
    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
コード例 #18
0
ファイル: treexmlparse.py プロジェクト: rodolfoap/treeline141
    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'
コード例 #19
0
    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)
コード例 #20
0
ファイル: treedoc.py プロジェクト: rodolfoap/treeline141
 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()
コード例 #21
0
 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))
コード例 #22
0
    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
コード例 #23
0
 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
コード例 #24
0
    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