def addElement(parent, datas): if len(datas) == 2 and datas[1][1] == None or \ len(datas) == 1: # Next item is word count n = 0 for i in range(datas[0][0]): n += 1 item = outlineItem(title="{} {}".format( datas[0][1], str(n)), _type=_type, parent=parent) if len(datas) == 2: item.setData(Outline.setGoal, datas[1][0]) # parent.appendChild(item) else: n = 0 for i in range(datas[0][0]): n += 1 item = outlineItem(title="{} {}".format( datas[0][1], str(n)), _type="folder", parent=parent) # parent.appendChild(item) addElement(item, datas[1:])
def addElement(parent, datas): if len(datas) == 2 and datas[1][1] == None or \ len(datas) == 1: # Next item is word count n = 0 for i in range(datas[0][0]): n += 1 item = outlineItem(title="{} {}".format( datas[0][1], str(n)), _type=_type, parent=parent) if len(datas) == 2: item.setData(Outline.setGoal, datas[1][0]) # parent.appendChild(item) else: n = 0 for i in range(datas[0][0]): n += 1 item = outlineItem(title="{} {}".format( datas[0][1], str(n)), _type="folder", parent=parent) # parent.appendChild(item) addElement(item, datas[1:])
def outlineModelBasic(MWEmptyProject): """Returns an outlineModel with a few items: * Folder * Text * Text """ from manuskript.models import outlineItem mdl = MWEmptyProject.mdlOutline root = mdl.rootItem f = outlineItem(title="Folder", parent=root) t1 = outlineItem(title="Text", _type="md", parent=f) t2 = outlineItem(title="Text", _type="md", parent=root) return mdl
def outlineModelBasic(MWEmptyProject): """Returns an outlineModel with a few items: * Folder * Text * Text """ from manuskript.models import outlineItem mdl = MWEmptyProject.mdlOutline root = mdl.rootItem f = outlineItem(title="Folder", parent=root) t1 = outlineItem(title="Text", _type="md", parent=f) t2 = outlineItem(title="Text", _type="md", parent=root) return mdl
def outlineFromMMD(text, parent): """ Creates outlineItem from multimarkdown file. @param text: content of the file @param parent: appends item to parent (outlineItem) @return: outlineItem """ item = outlineItem(parent=parent) md, body = parseMMDFile(text, asDict=True) # Store metadata for k in md: if k in Outline.__members__: item.setData(Outline.__members__[k], str(md[k])) # Store body item.setData(Outline.text, str(body)) # Set file format to "md" # (Old version of manuskript had different file formats: text, t2t, html and md) # If file format is html, convert to plain text: if item.type() == "html": item.setData(Outline.text, HTML2PlainText(body)) if item.type() in ["txt", "t2t", "html"]: item.setData(Outline.type, "md") return item
def outlineFromMMD(text, parent): """ Creates outlineItem from multimarkdown file. @param text: content of the file @param parent: appends item to parent (outlineItem) @return: outlineItem """ item = outlineItem(parent=parent) md, body = parseMMDFile(text, asDict=True) # Store metadata for k in md: if k in Outline.__members__: item.setData(Outline.__members__[k], str(md[k])) # Store body item.setData(Outline.text, str(body)) # Set file format to "md" # (Old version of manuskript had different file formats: text, t2t, html and md) # If file format is html, convert to plain text: if item.type() == "html": item.setData(Outline.text, HTML2PlainText(body)) if item.type() in ["txt", "t2t", "html"]: item.setData(Outline.type, "md") return item
def __init__(self, parent): QAbstractItemModel.__init__(self, parent) self.rootItem = outlineItem(self, title="Root", ID="0") # Stores removed item, in order to remove them on disk when saving, depending on the file format. self.removed = [] self._removingRows = False
def createNewText(self): item = self._index.internalPointer() newItem = outlineItem(title=qApp.translate("outlineBasics", "New"), _type=settings.defaultTextType) self._index.model().insertItem(newItem, item.row() + 1, item.parent().index()) self.setCurrentModelIndex(newItem.index())
def __init__(self, parent): QAbstractItemModel.__init__(self, parent) self.rootItem = outlineItem(self, title="Root", ID="0") # Stores removed item, in order to remove them on disk when saving, depending on the file format. self.removed = [] self._removingRows = False
def saveContent(content, parent): if content.strip(): child = outlineItem(title=parent.title(), parent=parent, _type="md") child._data[Outline.text] = content items.append(child) return ""
def loadFromXML(self, xml, fromString=False): "Load from xml. Assume that xml is a filename. If fromString=True, xml is the content." if not fromString: root = ET.parse(xml) else: root = ET.fromstring(xml) self.rootItem = outlineItem(model=self, xml=ET.tostring(root), ID="0") self.rootItem.checkIDs()
def loadFromXML(self, xml, fromString=False): "Load from xml. Assume that xml is a filename. If fromString=True, xml is the content." if not fromString: root = ET.parse(xml) else: root = ET.fromstring(xml) self.rootItem = outlineItem(model=self, xml=ET.tostring(root), ID="0") self.rootItem.checkIDs()
def test_outlineItemColors(): from manuskript.models import outlineItem item = outlineItem(title="Test") r = F.outlineItemColors(item) for i in ["POV", "Label", "Progress", "Compile"]: assert i in r from PyQt5.QtGui import QColor assert r["Compile"].name(QColor.HexArgb) == "#00000000"
def test_outlineItemColors(): from manuskript.models import outlineItem item = outlineItem(title="Test") r = F.outlineItemColors(item) for i in ["POV", "Label", "Progress", "Compile"]: assert i in r from PyQt5.QtGui import QColor assert r["Compile"].name(QColor.HexArgb) == "#00000000"
def addItem(self, _type="folder"): if len(self.selectedIndexes()) == 0: parent = self.rootIndex() else: parent = self.currentIndex() if _type == "text": _type = settings.defaultTextType item = outlineItem(title=qApp.translate("outlineBasics", "New"), _type=_type) self.model().appendItem(item, parent)
def addFile(f): fName, fExt = os.path.splitext(f) if fExt.lower() in ext: try: with open(os.path.join(dirpath, f), "r", encoding="utf-8") as fr: content = fr.read() child = outlineItem(title=fName, _type="md", parent=item) child._data[Outline.text] = content items.append(child) except UnicodeDecodeError: # Probably not a text file pass
def addFile(f): fName, fExt = os.path.splitext(f) if fExt.lower() in ext: try: with open(os.path.join(dirpath, f), "r") as fr: content = fr.read() child = outlineItem(title=fName, _type="md", parent=item) child._data[Outline.text] = content items.append(child) except UnicodeDecodeError: # Probably not a text file pass
def decodeMimeData(self, data): if not data.hasFormat("application/xml"): return None encodedData = bytes(data.data("application/xml")).decode() root = ET.XML(encodedData) if root is None: return None if root.tag != "outlineItems": return None items = [] for child in root: if child.tag == "outlineItem": item = outlineItem(xml=ET.tostring(child)) items.append(item) # We remove every item whose parent is also in items, otherwise it gets # duplicated. (https://github.com/olivierkes/manuskript/issues/169) # For example if selecting: # - Parent # - Child # And dragging them, items encoded in mime data are: [Parent, Child], # but Child is already contained in Parent, so if we do nothing we end # up with: # - Parent # - Child # - Child newItems = items[:] IDs = [i.ID() for i in items] def checkIfChildIsPresent(item): # Recursively check every children of item, to see if any is in # the list of items to copy. If so, we remove it from the list. for c in item.children(): # We check if children is in the selection # and if it hasn't been removed yet if c.ID() in IDs and c.ID() in [i.ID() for i in newItems]: # Remove item by ID newItems.remove([i for i in newItems if i.ID() == c.ID()][0]) checkIfChildIsPresent(c) for i in items: checkIfChildIsPresent(i) items = newItems return items
def decodeMimeData(self, data): if not data.hasFormat("application/xml"): return None encodedData = bytes(data.data("application/xml")).decode() root = ET.XML(encodedData) if root is None: return None if root.tag != "outlineItems": return None items = [] for child in root: if child.tag == "outlineItem": item = outlineItem(xml=ET.tostring(child)) items.append(item) # We remove every item whose parent is also in items, otherwise it gets # duplicated. (https://github.com/olivierkes/manuskript/issues/169) # For example if selecting: # - Parent # - Child # And dragging them, items encoded in mime data are: [Parent, Child], # but Child is already contained in Parent, so if we do nothing we end # up with: # - Parent # - Child # - Child newItems = items[:] IDs = [i.ID() for i in items] def checkIfChildIsPresent(item): # Recursively check every children of item, to see if any is in # the list of items to copy. If so, we remove it from the list. for c in item.children(): # We check if children is in the selection # and if it hasn't been removed yet if c.ID() in IDs and c.ID() in [i.ID() for i in newItems]: # Remove item by ID newItems.remove([i for i in newItems if i.ID() == c.ID()][0]) checkIfChildIsPresent(c) for i in items: checkIfChildIsPresent(i) items = newItems return items
def parseItems(cls, underElement, parentItem=None): items = [] title = underElement.get('text') if title is not None: card = outlineItem(parent=parentItem, title=title) items.append(card) body = "" note = underElement.get('_note') if note is not None and not cls.isWhitespaceOnly(note): #body = cls.restoreNewLines(note) body = note children = underElement.findall('outline') if children is not None and len(children) > 0: for el in children: items.extend(cls.parseItems(el, card)) else: card.setData(Outline.type, 'md') card.setData(Outline.text, body) return items
def startImport(self, outlineModel): """ Where most of the magic happens. Is used by preview and by doImport (actual import). `outlineModel` is the model where the imported items are added. FIXME: Optimisation: when adding many outlineItems, outlineItem.updateWordCount is a bottleneck. It gets called a crazy number of time, and its not necessary. """ items = [] # We find the current selected format F = self._format # Parent item ID = self.settingsWidget.importUnderID() parentItem = outlineModel.getItemByID(ID) # Import in top-level folder? if self.settingsWidget.importInTopLevelFolder(): parent = outlineItem(title=os.path.basename(self.fileName), parent=parentItem) parentItem = parent items.append(parent) # Calling the importer rItems = F.startImport(self.fileName, parentItem, self.settingsWidget) items.extend(rItems) # Do transformations items = self.doTransformations(items) return True
def addFolder(d): child = outlineItem(title=d, parent=item) items.append(child) stack[os.path.join(dirpath, d)] = child
def saveContent(content, parent): if content.strip(): child = outlineItem(title=parent.title(), parent=parent, _type="md") child._data[Outline.text] = content items.append(child) return ""
def addFolder(d): child = outlineItem(title=d, parent=item) items.append(child) stack[os.path.join(dirpath, d)] = child
def createNewText(self): item = self._index.internalPointer() newItem = outlineItem(title=qApp.translate("outlineBasics", "New"), _type=settings.defaultTextType) self._index.model().insertItem(newItem, item.row() + 1, item.parent().index()) self.setCurrentModelIndex(newItem.index())
def addTitle(name, parent, level): child = outlineItem(title=name, parent=parent) child.__miLevel = level items.append(child) return child
def outlineItemFolder(): '''Returns a folder outlineItem title "Folder".''' from manuskript.models import outlineItem return outlineItem(title="Folder")
def outlineItemText(): '''Returns a text outlineItem title "Text".''' from manuskript.models import outlineItem return outlineItem(title="Text", _type="md")
def parseItems(self, underElement, parentItem=None): items = [] # Title title = underElement.get('TEXT', "").replace("\n", " ") if not title: title = qApp.translate("Import", "Untitled") item = outlineItem(parent=parentItem, title=title) items.append(item) # URL url = underElement.get('LINK', None) # Rich text content content = "" content = underElement.find("richcontent") if content is not None: # In Freemind, can be note or node # Note: it's a note # Node: it's the title of the node, in rich text content_type = content.get("TYPE", "NOTE") content = ET.tostring(content.find("html")) if content and content_type == "NODE": # Content is title # convert rich text title (in html) to plain text title = HTML2PlainText(content) #.replace("\n", " ").strip() # Count the number of lines lines = [l.strip() for l in title.split("\n") if l.strip()] # If there is one line, we use it as title. # Otherwise we leave it to be inserted as a note. if len(lines) == 1: item.setData(Outline.title, "".join(lines)) content = "" if content: # Set the note content as text value content = HTML2MD(content) item.setData(Outline.notes, content) if url: # Set the url in notes item.setData(Outline.notes, item.data(Outline.notes) + "\n\n" + url) children = underElement.findall('node') # Process children if children is not None and len(children) > 0: for c in children: items.extend(self.parseItems(c, item)) # Process if no children elif self.getSetting("importTipAs").value() == "Text": # Transform item to text item.setData(Outline.type, 'md') # Move notes to text if item.data(Outline.notes): item.setData(Outline.text, item.data(Outline.notes)) item.setData(Outline.notes, "") return items
def parseItems(self, underElement, parentItem=None): items = [] # Title title = underElement.get('TEXT', "").replace("\n", " ") if not title: title = qApp.translate("Import", "Untitled") item = outlineItem(parent=parentItem, title=title) items.append(item) # URL url = underElement.get('LINK', None) # Rich text content content = "" content = underElement.find("richcontent") if content is not None: # In Freemind, can be note or node # Note: it's a note # Node: it's the title of the node, in rich text content_type = content.get("TYPE", "NOTE") content = ET.tostring(content.find("html")) if content and content_type == "NODE": # Content is title # convert rich text title (in html) to plain text title = HTML2PlainText(content) #.replace("\n", " ").strip() # Count the number of lines lines = [l.strip() for l in title.split("\n") if l.strip()] # If there is one line, we use it as title. # Otherwise we leave it to be inserted as a note. if len(lines) == 1: item.setData(Outline.title, "".join(lines)) content = "" if content: # Set the note content as text value content = HTML2MD(content) item.setData(Outline.notes, content) if url: # Set the url in notes item.setData(Outline.notes, item.data(Outline.notes) + "\n\n" + url) children = underElement.findall('node') # Process children if children is not None and len(children) > 0: for c in children: items.extend(self.parseItems(c, item)) # Process if no children elif self.getSetting("importTipAs").value() == "Text": # Transform item to text item.setData(Outline.type, 'md') # Move notes to text if item.data(Outline.notes): item.setData(Outline.text, item.data(Outline.notes)) item.setData(Outline.notes, "") return items
def addTitle(name, parent, level): child = outlineItem(title=name, parent=parent) child.__miLevel = level items.append(child) return child
def outlineItemFolder(): '''Returns a folder outlineItem title "Folder".''' from manuskript.models import outlineItem return outlineItem(title="Folder")
def outlineItemText(): '''Returns a text outlineItem title "Text".''' from manuskript.models import outlineItem return outlineItem(title="Text", _type="md")