From 316651245c866898a4550adcfe61ca17763683fd Mon Sep 17 00:00:00 2001 From: Olivier Keshavjee Date: Tue, 7 Nov 2017 12:50:40 +0100 Subject: [PATCH] Checkpoint: opml import can be previewed in tree view --- manuskript/importer/abstractImporter.py | 7 +- manuskript/importer/opmlImporter.py | 100 ++++++++++++------ manuskript/ui/importers/generalSettings_ui.py | 4 + manuskript/ui/importers/generalSettings_ui.ui | 7 ++ manuskript/ui/importers/importer.py | 27 ++++- manuskript/ui/importers/importer_ui.py | 5 +- manuskript/ui/importers/importer_ui.ui | 14 +-- 7 files changed, 117 insertions(+), 47 deletions(-) diff --git a/manuskript/importer/abstractImporter.py b/manuskript/importer/abstractImporter.py index 822ebe5..7c75a68 100644 --- a/manuskript/importer/abstractImporter.py +++ b/manuskript/importer/abstractImporter.py @@ -22,10 +22,11 @@ class abstractImporter: # For folder, use "<>" icon = "" - @classmethod - def startImport(cls, filePath): + def startImport(self, filePath, settingsWidget): """ - Takes a str path to the file/folder to import, and return `outlineItem`s. + Takes a str path to the file/folder to import, and the settingsWidget + returnend by `self.settingsWidget()` containing the user set settings, + and return `outlineItem`s. """ pass diff --git a/manuskript/importer/opmlImporter.py b/manuskript/importer/opmlImporter.py index 636d7b4..aff3728 100644 --- a/manuskript/importer/opmlImporter.py +++ b/manuskript/importer/opmlImporter.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # --!-- coding: utf8 --!-- -from PyQt5.QtWidgets import QMessageBox +from PyQt5.QtWidgets import qApp, QMessageBox from manuskript.models.outlineModel import outlineItem from manuskript.enums import Outline from lxml import etree as ET @@ -15,9 +15,56 @@ class opmlImporter(abstractImporter): fileFormat = "OPML Files (*.opml)" icon = "text-x-opml+xml" + @classmethod + def startImport(cls, filePath, parentItem, settingsWidget): + """ + Import/export outline cards in OPML format. + """ + ret = False + + try: + with open(filePath, 'r') as opmlFile: + opmlContent = cls.saveNewlines(opmlFile.read()) + except: + QMessageBox.critical(settingsWidget, + qApp.translate("Import", "OPML Import"), + qApp.translate("Import", "File open failed.")) + return None + + parsed = ET.fromstring(bytes(opmlContent, 'utf-8')) + + opmlNode = parsed + bodyNode = opmlNode.find("body") + items = [] + + if bodyNode is not None: + outlineEls = bodyNode.findall("outline") + + if outlineEls is not None: + for element in outlineEls: + items.append(cls.parseItems(element, parentItem)) + ret = True + + if ret: + #QMessageBox.information( + #settingsWidget, + #qApp.translate("Import", "OPML Import"), + #qApp.translate("Import", "Import Complete.")) + pass + else: + QMessageBox.critical( + settingsWidget, + qApp.translate("Import", "OPML Import"), + qApp.translate("Import", "This does not appear to be a valid OPML file.")) + + return None + + return items + def importOpml(opmlFilePath, idx): """ Import/export outline cards in OPML format. + #FIXME: delete me when done with startImport """ ret = False mw = mainWindow() @@ -26,7 +73,6 @@ class opmlImporter(abstractImporter): with open(opmlFilePath, 'r') as opmlFile: opmlContent = saveNewlines(opmlFile.read()) except: - # TODO: Translation QMessageBox.critical(mw, mw.tr("OPML Import"), mw.tr("File open failed.")) return False @@ -67,48 +113,30 @@ class opmlImporter(abstractImporter): return ret - - def parseItems(underElement, parentItem): - text = underElement.get('text') - if text is not None: - - # In the case where the title is exceptionally long, trim it so it isn't - # distracting in the tab label - title = text[0:32] - if len(title) < len(text): - title += '...' + @classmethod + def parseItems(cls, underElement, parentItem=None): + title = underElement.get('text') + if title is not None: card = outlineItem(parent=parentItem, title=title) body = "" - summary = "" note = underElement.get('_note') - if note is not None and not isWhitespaceOnly(note): - body = restoreNewLines(note) - summary = body[0:128] - else: - - # There's no note (body), but there is a title. Fill the - # body with the title to support cards that consist only - # of a title. - body = text - - card.setData(Outline.summaryFull.value, summary) + if note is not None and not cls.isWhitespaceOnly(note): + body = cls.restoreNewLines(note) children = underElement.findall('outline') if children is not None and len(children) > 0: for el in children: - parseItems(el, card) + cls.parseItems(el, card) else: card.setData(Outline.type.value, 'md') card.setData(Outline.text.value, body) - # I assume I don't have to do the following - # parentItem.appendChild(card) + return card - return - - def saveNewlines(inString): + @classmethod + def saveNewlines(cls, inString): """ Since XML parsers are notorious for stripping out significant newlines, save them in a form we can restore after the parse. @@ -118,17 +146,19 @@ class opmlImporter(abstractImporter): return inString - def restoreNewLines(inString): + @classmethod + def restoreNewLines(cls, inString): """ Restore any significant newlines """ return inString.replace("{{lf}}", "\n") - def isWhitespaceOnly(inString): + @classmethod + def isWhitespaceOnly(cls, inString): """ Determine whether or not a string only contains whitespace. """ - str = restoreNewLines(inString) - str = ''.join(str.split()) + s = cls.restoreNewLines(inString) + s = ''.join(s.split()) - return len(str) is 0 + return len(s) is 0 diff --git a/manuskript/ui/importers/generalSettings_ui.py b/manuskript/ui/importers/generalSettings_ui.py index 078ca2b..0faed4c 100644 --- a/manuskript/ui/importers/generalSettings_ui.py +++ b/manuskript/ui/importers/generalSettings_ui.py @@ -49,6 +49,9 @@ class Ui_generalSettings(object): self.treeGeneralParent.setHeaderHidden(True) self.treeGeneralParent.setObjectName("treeGeneralParent") self.formLayout_4.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.treeGeneralParent) + self.chkGeneralTrimTitles = QtWidgets.QCheckBox(self.general) + self.chkGeneralTrimTitles.setObjectName("chkGeneralTrimTitles") + self.formLayout_4.setWidget(2, QtWidgets.QFormLayout.SpanningRole, self.chkGeneralTrimTitles) self.verticalLayout_5.addLayout(self.formLayout_4) self.toolBox.addItem(self.general, "") self.verticalLayout_2.addWidget(self.toolBox) @@ -63,5 +66,6 @@ class Ui_generalSettings(object): generalSettings.setWindowTitle(_translate("generalSettings", "Form")) self.chkGeneralParent.setText(_translate("generalSettings", "Import under:")) self.chkGeneralSplitScenes.setText(_translate("generalSettings", "Split scenes at:")) + self.chkGeneralTrimTitles.setText(_translate("generalSettings", "Trim long titles (> 32 chars)")) self.toolBox.setItemText(self.toolBox.indexOf(self.general), _translate("generalSettings", "General")) diff --git a/manuskript/ui/importers/generalSettings_ui.ui b/manuskript/ui/importers/generalSettings_ui.ui index 53446d2..45fe6ef 100644 --- a/manuskript/ui/importers/generalSettings_ui.ui +++ b/manuskript/ui/importers/generalSettings_ui.ui @@ -90,6 +90,13 @@ QToolBox::tab:selected, QToolBox::tab:hover{ + + + + Trim long titles (> 32 chars) + + + diff --git a/manuskript/ui/importers/importer.py b/manuskript/ui/importers/importer.py index 72152f3..ea527c4 100644 --- a/manuskript/ui/importers/importer.py +++ b/manuskript/ui/importers/importer.py @@ -157,5 +157,30 @@ class importerDialog(QWidget, Ui_importer): ############################################################################ def preview(self): - # TODO + + # We find the current selected format + F = self.currentFormat() + + # Temporary outlineModel previewModel = outlineModel(self) + + # Calling the importer in a temporary model + items = F.startImport(self.fileName, + previewModel.rootItem, + self.settingsWidget) + + # Do transformations + # TODO + + if items: + self.tree.setModel(previewModel) + for i in range(1, previewModel.columnCount()): + self.tree.hideColumn(i) + + def startImport(self): + pass + + # Note: dont forget to emit: mdl.layoutChanged.emit() + # Maybe: mw.treeRedacOutline.viewport().update() + + diff --git a/manuskript/ui/importers/importer_ui.py b/manuskript/ui/importers/importer_ui.py index 44afddc..67f49db 100644 --- a/manuskript/ui/importers/importer_ui.py +++ b/manuskript/ui/importers/importer_ui.py @@ -80,7 +80,9 @@ class Ui_importer(object): self.splitter_2 = QtWidgets.QSplitter(self.grpPreview) self.splitter_2.setOrientation(QtCore.Qt.Horizontal) self.splitter_2.setObjectName("splitter_2") - self.tree = treeView(self.splitter_2) + self.tree = QtWidgets.QTreeView(self.splitter_2) + self.tree.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) + self.tree.setHeaderHidden(True) self.tree.setObjectName("tree") self.editor = mainEditor(self.splitter_2) self.editor.setObjectName("editor") @@ -102,4 +104,3 @@ class Ui_importer(object): self.grpPreview.setTitle(_translate("importer", "Preview")) from manuskript.ui.editors.mainEditor import mainEditor -from manuskript.ui.views.treeView import treeView diff --git a/manuskript/ui/importers/importer_ui.ui b/manuskript/ui/importers/importer_ui.ui index afb053e..0281cd0 100644 --- a/manuskript/ui/importers/importer_ui.ui +++ b/manuskript/ui/importers/importer_ui.ui @@ -178,7 +178,14 @@ Qt::Horizontal - + + + QAbstractItemView::NoEditTriggers + + + true + + @@ -189,11 +196,6 @@ - - treeView - QTreeView -
manuskript.ui.views.treeView.h
-
mainEditor QWidget