Restructure Build Novel Project tool to allow ODT save
This commit is contained in:
+130
-91
@@ -46,7 +46,7 @@ from PyQt5.QtWidgets import (
|
|||||||
|
|
||||||
from nw.common import fuzzyTime, makeFileNameSafe
|
from nw.common import fuzzyTime, makeFileNameSafe
|
||||||
from nw.gui.custom import QSwitch
|
from nw.gui.custom import QSwitch
|
||||||
from nw.core import ToHtml
|
from nw.core import ToHtml, ToOdt
|
||||||
from nw.constants import (
|
from nw.constants import (
|
||||||
nwConst, nwAlert, nwFiles, nwItemType, nwItemLayout, nwItemClass
|
nwConst, nwAlert, nwFiles, nwItemType, nwItemLayout, nwItemClass
|
||||||
)
|
)
|
||||||
@@ -56,13 +56,14 @@ logger = logging.getLogger(__name__)
|
|||||||
class GuiBuildNovel(QDialog):
|
class GuiBuildNovel(QDialog):
|
||||||
|
|
||||||
FMT_ODT = 1
|
FMT_ODT = 1
|
||||||
FMT_PDF = 2
|
FMT_FODT = 2
|
||||||
FMT_HTM = 3
|
FMT_PDF = 3
|
||||||
FMT_MD = 4
|
FMT_HTM = 4
|
||||||
FMT_NWD = 5
|
FMT_MD = 5
|
||||||
FMT_TXT = 6
|
FMT_NWD = 6
|
||||||
FMT_JSON_H = 7
|
FMT_TXT = 7
|
||||||
FMT_JSON_M = 8
|
FMT_JSON_H = 8
|
||||||
|
FMT_JSON_M = 9
|
||||||
|
|
||||||
def __init__(self, theParent, theProject):
|
def __init__(self, theParent, theProject):
|
||||||
QDialog.__init__(self, theParent)
|
QDialog.__init__(self, theParent)
|
||||||
@@ -386,6 +387,10 @@ class GuiBuildNovel(QDialog):
|
|||||||
self.saveODT.triggered.connect(lambda: self._saveDocument(self.FMT_ODT))
|
self.saveODT.triggered.connect(lambda: self._saveDocument(self.FMT_ODT))
|
||||||
self.saveMenu.addAction(self.saveODT)
|
self.saveMenu.addAction(self.saveODT)
|
||||||
|
|
||||||
|
self.saveFODT = QAction("Flat Open Document (.fodt)", self)
|
||||||
|
self.saveFODT.triggered.connect(lambda: self._saveDocument(self.FMT_FODT))
|
||||||
|
self.saveMenu.addAction(self.saveFODT)
|
||||||
|
|
||||||
self.savePDF = QAction("Portable Document Format (.pdf)", self)
|
self.savePDF = QAction("Portable Document Format (.pdf)", self)
|
||||||
self.savePDF.triggered.connect(lambda: self._saveDocument(self.FMT_PDF))
|
self.savePDF.triggered.connect(lambda: self._saveDocument(self.FMT_PDF))
|
||||||
self.saveMenu.addAction(self.savePDF)
|
self.saveMenu.addAction(self.savePDF)
|
||||||
@@ -533,49 +538,18 @@ class GuiBuildNovel(QDialog):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
##
|
##
|
||||||
# Slots
|
# Slots and Related
|
||||||
##
|
##
|
||||||
|
|
||||||
def _buildPreview(self):
|
def _buildPreview(self):
|
||||||
"""Build a preview of the project in the document viewer.
|
"""Build a preview of the project in the document viewer.
|
||||||
"""
|
"""
|
||||||
# Get Settings
|
# Get Settings
|
||||||
fmtTitle = self.fmtTitle.text().strip()
|
justifyText = self.justifyText.isChecked()
|
||||||
fmtChapter = self.fmtChapter.text().strip()
|
noStyling = self.noStyling.isChecked()
|
||||||
fmtUnnumbered = self.fmtUnnumbered.text().strip()
|
textFont = self.textFont.text()
|
||||||
fmtScene = self.fmtScene.text().strip()
|
textSize = self.textSize.value()
|
||||||
fmtSection = self.fmtSection.text().strip()
|
replaceTabs = self.replaceTabs.isChecked()
|
||||||
justifyText = self.justifyText.isChecked()
|
|
||||||
noStyling = self.noStyling.isChecked()
|
|
||||||
textFont = self.textFont.text()
|
|
||||||
textSize = self.textSize.value()
|
|
||||||
incSynopsis = self.includeSynopsis.isChecked()
|
|
||||||
incComments = self.includeComments.isChecked()
|
|
||||||
incKeywords = self.includeKeywords.isChecked()
|
|
||||||
novelFiles = self.novelFiles.isChecked()
|
|
||||||
noteFiles = self.noteFiles.isChecked()
|
|
||||||
ignoreFlag = self.ignoreFlag.isChecked()
|
|
||||||
includeBody = self.includeBody.isChecked()
|
|
||||||
replaceTabs = self.replaceTabs.isChecked()
|
|
||||||
|
|
||||||
makeHtml = ToHtml(self.theProject, self.theParent)
|
|
||||||
makeHtml.setTitleFormat(fmtTitle)
|
|
||||||
makeHtml.setChapterFormat(fmtChapter)
|
|
||||||
makeHtml.setUnNumberedFormat(fmtUnnumbered)
|
|
||||||
makeHtml.setSceneFormat(fmtScene, fmtScene == "")
|
|
||||||
makeHtml.setSectionFormat(fmtSection, fmtSection == "")
|
|
||||||
makeHtml.setBodyText(includeBody)
|
|
||||||
makeHtml.setSynopsis(incSynopsis)
|
|
||||||
makeHtml.setComments(incComments)
|
|
||||||
makeHtml.setKeywords(incKeywords)
|
|
||||||
makeHtml.setJustify(justifyText)
|
|
||||||
makeHtml.setStyles(not noStyling)
|
|
||||||
|
|
||||||
# Make sure the tree order is correct
|
|
||||||
self.theParent.treeView.flushTreeOrder()
|
|
||||||
|
|
||||||
self.buildProgress.setMaximum(len(self.theProject.projTree))
|
|
||||||
self.buildProgress.setValue(0)
|
|
||||||
|
|
||||||
tStart = int(time())
|
tStart = int(time())
|
||||||
|
|
||||||
@@ -583,52 +557,8 @@ class GuiBuildNovel(QDialog):
|
|||||||
self.htmlStyle = []
|
self.htmlStyle = []
|
||||||
self.nwdText = []
|
self.nwdText = []
|
||||||
|
|
||||||
htmlSize = 0
|
makeHtml = ToHtml(self.theProject, self.theParent)
|
||||||
|
htmlSize = self._doBuild(makeHtml)
|
||||||
for nItt, tItem in enumerate(self.theProject.projTree):
|
|
||||||
|
|
||||||
noteRoot = noteFiles
|
|
||||||
noteRoot &= tItem.itemType == nwItemType.ROOT
|
|
||||||
noteRoot &= tItem.itemClass != nwItemClass.NOVEL
|
|
||||||
noteRoot &= tItem.itemClass != nwItemClass.ARCHIVE
|
|
||||||
|
|
||||||
try:
|
|
||||||
if noteRoot:
|
|
||||||
# Add headers for root folders of notes
|
|
||||||
makeHtml.addRootHeading(tItem.itemHandle)
|
|
||||||
makeHtml.doConvert()
|
|
||||||
self.htmlText.append(makeHtml.getResult())
|
|
||||||
self.nwdText.append(makeHtml.getFilteredMarkdown())
|
|
||||||
htmlSize += makeHtml.getResultSize()
|
|
||||||
|
|
||||||
elif self._checkInclude(tItem, noteFiles, novelFiles, ignoreFlag):
|
|
||||||
makeHtml.setText(tItem.itemHandle)
|
|
||||||
makeHtml.doAutoReplace()
|
|
||||||
makeHtml.tokenizeText()
|
|
||||||
makeHtml.doHeaders()
|
|
||||||
makeHtml.doConvert()
|
|
||||||
makeHtml.doPostProcessing()
|
|
||||||
self.htmlText.append(makeHtml.getResult())
|
|
||||||
self.nwdText.append(makeHtml.getFilteredMarkdown())
|
|
||||||
htmlSize += makeHtml.getResultSize()
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error("Failed to generate html of document '%s'" % tItem.itemHandle)
|
|
||||||
logger.error(str(e))
|
|
||||||
self.docView.setText((
|
|
||||||
"Failed to generate preview. "
|
|
||||||
"Document with title '%s' could not be parsed."
|
|
||||||
) % tItem.itemName)
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Update progress bar, also for skipped items
|
|
||||||
self.buildProgress.setValue(nItt+1)
|
|
||||||
|
|
||||||
if makeHtml.errData:
|
|
||||||
self.theParent.makeAlert((
|
|
||||||
"There were problems when building the project:"
|
|
||||||
"<br>- %s"
|
|
||||||
) % "<br>- ".join(makeHtml.errData), nwAlert.ERROR)
|
|
||||||
|
|
||||||
if replaceTabs:
|
if replaceTabs:
|
||||||
htmlText = []
|
htmlText = []
|
||||||
@@ -668,6 +598,103 @@ class GuiBuildNovel(QDialog):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def _doBuild(self, bldObj):
|
||||||
|
"""Rund the build with a specific build object.
|
||||||
|
"""
|
||||||
|
# Get Settings
|
||||||
|
fmtTitle = self.fmtTitle.text().strip()
|
||||||
|
fmtChapter = self.fmtChapter.text().strip()
|
||||||
|
fmtUnnumbered = self.fmtUnnumbered.text().strip()
|
||||||
|
fmtScene = self.fmtScene.text().strip()
|
||||||
|
fmtSection = self.fmtSection.text().strip()
|
||||||
|
justifyText = self.justifyText.isChecked()
|
||||||
|
noStyling = self.noStyling.isChecked()
|
||||||
|
incSynopsis = self.includeSynopsis.isChecked()
|
||||||
|
incComments = self.includeComments.isChecked()
|
||||||
|
incKeywords = self.includeKeywords.isChecked()
|
||||||
|
novelFiles = self.novelFiles.isChecked()
|
||||||
|
noteFiles = self.noteFiles.isChecked()
|
||||||
|
ignoreFlag = self.ignoreFlag.isChecked()
|
||||||
|
includeBody = self.includeBody.isChecked()
|
||||||
|
|
||||||
|
isHtml = isinstance(bldObj, ToHtml)
|
||||||
|
isOdt = isinstance(bldObj, ToOdt)
|
||||||
|
|
||||||
|
bldObj.setTitleFormat(fmtTitle)
|
||||||
|
bldObj.setChapterFormat(fmtChapter)
|
||||||
|
bldObj.setUnNumberedFormat(fmtUnnumbered)
|
||||||
|
bldObj.setSceneFormat(fmtScene, fmtScene == "")
|
||||||
|
bldObj.setSectionFormat(fmtSection, fmtSection == "")
|
||||||
|
bldObj.setBodyText(includeBody)
|
||||||
|
bldObj.setSynopsis(incSynopsis)
|
||||||
|
bldObj.setComments(incComments)
|
||||||
|
bldObj.setKeywords(incKeywords)
|
||||||
|
bldObj.setJustify(justifyText)
|
||||||
|
|
||||||
|
if isHtml:
|
||||||
|
bldObj.setStyles(not noStyling)
|
||||||
|
|
||||||
|
if isOdt:
|
||||||
|
bldObj.initDocument()
|
||||||
|
|
||||||
|
# Make sure the tree order is correct
|
||||||
|
self.theParent.treeView.flushTreeOrder()
|
||||||
|
|
||||||
|
self.buildProgress.setMaximum(len(self.theProject.projTree))
|
||||||
|
self.buildProgress.setValue(0)
|
||||||
|
|
||||||
|
accSize = 0
|
||||||
|
|
||||||
|
for nItt, tItem in enumerate(self.theProject.projTree):
|
||||||
|
|
||||||
|
noteRoot = noteFiles
|
||||||
|
noteRoot &= tItem.itemType == nwItemType.ROOT
|
||||||
|
noteRoot &= tItem.itemClass != nwItemClass.NOVEL
|
||||||
|
noteRoot &= tItem.itemClass != nwItemClass.ARCHIVE
|
||||||
|
|
||||||
|
try:
|
||||||
|
if noteRoot:
|
||||||
|
# Add headers for root folders of notes
|
||||||
|
bldObj.addRootHeading(tItem.itemHandle)
|
||||||
|
bldObj.doConvert()
|
||||||
|
self.htmlText.append(bldObj.getResult())
|
||||||
|
self.nwdText.append(bldObj.getFilteredMarkdown())
|
||||||
|
accSize += bldObj.getResultSize()
|
||||||
|
|
||||||
|
elif self._checkInclude(tItem, noteFiles, novelFiles, ignoreFlag):
|
||||||
|
bldObj.setText(tItem.itemHandle)
|
||||||
|
bldObj.doAutoReplace()
|
||||||
|
bldObj.tokenizeText()
|
||||||
|
bldObj.doHeaders()
|
||||||
|
bldObj.doConvert()
|
||||||
|
bldObj.doPostProcessing()
|
||||||
|
self.htmlText.append(bldObj.getResult())
|
||||||
|
self.nwdText.append(bldObj.getFilteredMarkdown())
|
||||||
|
accSize += bldObj.getResultSize()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("Failed to generate html of document '%s'" % tItem.itemHandle)
|
||||||
|
logger.error(str(e))
|
||||||
|
self.docView.setText((
|
||||||
|
"Failed to generate preview. "
|
||||||
|
"Document with title '%s' could not be parsed."
|
||||||
|
) % tItem.itemName)
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Update progress bar, also for skipped items
|
||||||
|
self.buildProgress.setValue(nItt+1)
|
||||||
|
|
||||||
|
if isOdt:
|
||||||
|
bldObj.closeDocument()
|
||||||
|
|
||||||
|
if bldObj.errData:
|
||||||
|
self.theParent.makeAlert((
|
||||||
|
"There were problems when building the project:"
|
||||||
|
"<br>- %s"
|
||||||
|
) % "<br>- ".join(bldObj.errData), nwAlert.ERROR)
|
||||||
|
|
||||||
|
return accSize
|
||||||
|
|
||||||
def _checkInclude(self, theItem, noteFiles, novelFiles, ignoreFlag):
|
def _checkInclude(self, theItem, noteFiles, novelFiles, ignoreFlag):
|
||||||
"""This function checks whether a file should be included in the
|
"""This function checks whether a file should be included in the
|
||||||
export or not. For standard note and novel files, this is
|
export or not. For standard note and novel files, this is
|
||||||
@@ -723,6 +750,11 @@ class GuiBuildNovel(QDialog):
|
|||||||
textFmt = "Open Document"
|
textFmt = "Open Document"
|
||||||
outTool = "Qt"
|
outTool = "Qt"
|
||||||
|
|
||||||
|
elif theFormat == self.FMT_FODT:
|
||||||
|
fileExt = "fodt"
|
||||||
|
textFmt = "Flat Open Document"
|
||||||
|
outTool = "NW2"
|
||||||
|
|
||||||
elif theFormat == self.FMT_PDF:
|
elif theFormat == self.FMT_PDF:
|
||||||
fileExt = "pdf"
|
fileExt = "pdf"
|
||||||
textFmt = "PDF"
|
textFmt = "PDF"
|
||||||
@@ -866,6 +898,13 @@ class GuiBuildNovel(QDialog):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
errMsg = str(e)
|
errMsg = str(e)
|
||||||
|
|
||||||
|
elif outTool == "NW2":
|
||||||
|
|
||||||
|
if theFormat == self.FMT_FODT:
|
||||||
|
makeOdt = ToOdt(self.theProject, self.theParent)
|
||||||
|
self._doBuild(makeOdt)
|
||||||
|
wSuccess = True
|
||||||
|
|
||||||
elif outTool == "QtPrint" and theFormat == self.FMT_PDF:
|
elif outTool == "QtPrint" and theFormat == self.FMT_PDF:
|
||||||
try:
|
try:
|
||||||
thePrinter = QPrinter()
|
thePrinter = QPrinter()
|
||||||
|
|||||||
Reference in New Issue
Block a user