diff --git a/nw/constants.py b/nw/constants.py index 9c56b012..a5244d46 100644 --- a/nw/constants.py +++ b/nw/constants.py @@ -19,6 +19,7 @@ class nwFiles(): PROJ_DICT = "wordlist.txt" SESS_INFO = "sessionInfo.log" INDEX_FILE = "tagsIndex.json" + EXPORT_OPT = "exportOptions.json" # END Class nwFiles diff --git a/nw/gui/configeditor.py b/nw/gui/configeditor.py index 08b6cefd..5010e500 100644 --- a/nw/gui/configeditor.py +++ b/nw/gui/configeditor.py @@ -282,6 +282,7 @@ class GuiConfigEditGeneral(QWidget): if newDir: self.projBackupPath.setText(newDir) return True + return False # END Class GuiConfigEditGeneral diff --git a/nw/gui/docdetails.py b/nw/gui/docdetails.py index 804b43bc..888e295e 100644 --- a/nw/gui/docdetails.py +++ b/nw/gui/docdetails.py @@ -54,7 +54,7 @@ class GuiDocDetails(QFrame): QLabel("") ] - colOne = ["Name","Status","Class","Layout"] + colOne = ["Label","Status","Class","Layout"] for nRow in range(4): lblOne = QLabel(colOne[nRow]) lblOne.setFont(self.fntOne) diff --git a/nw/gui/export.py b/nw/gui/export.py index 871e98ee..995666f3 100644 --- a/nw/gui/export.py +++ b/nw/gui/export.py @@ -11,6 +11,7 @@ """ import logging +import json import nw from os import path @@ -19,10 +20,12 @@ from PyQt5.QtCore import Qt, QSize from PyQt5.QtSvg import QSvgWidget from PyQt5.QtWidgets import ( QDialog, QHBoxLayout, QVBoxLayout, QWidget, QTabWidget, QDialogButtonBox, QGridLayout, - QGroupBox, QCheckBox, QLabel, QComboBox, QLineEdit, QPushButton + QGroupBox, QCheckBox, QLabel, QComboBox, QLineEdit, QPushButton, QFileDialog ) from nw.tools.translate import numberToWord +from nw.common import checkString, checkBool, checkInt +from nw.constants import nwFiles logger = logging.getLogger(__name__) @@ -36,6 +39,7 @@ class GuiExport(QDialog): self.mainConf = nw.CONFIG self.theParent = theParent self.theProject = theProject + self.optState = ExportLastState(self.theProject) self.outerBox = QHBoxLayout() self.innerBox = QVBoxLayout() @@ -47,7 +51,7 @@ class GuiExport(QDialog): self.svgGradient.setFixedSize(QSize(64,64)) self.theProject.countStatus() - self.tabMain = GuiExportMain(self.theParent, self.theProject) + self.tabMain = GuiExportMain(self.theParent, self.theProject, self.optState) self.tabWidget = QTabWidget() self.tabWidget.addTab(self.tabMain, "Settings") @@ -73,8 +77,30 @@ class GuiExport(QDialog): ## def _doSave(self): + logger.verbose("GuiExport save button clicked") + + wNovel = self.tabMain.expNovel.isChecked() + wNotes = self.tabMain.expNotes.isChecked() + wTOC = self.tabMain.expTOC.isChecked() + eFormat = self.tabMain.outputFormat.currentData() + wComments = self.tabMain.outputComments.isChecked() + chFormat = self.tabMain.chapterFormat.text() + scFormat = self.tabMain.sceneFormat.text() + saveTo = self.tabMain.exportPath.text() + + self.optState.setSetting("wNovel", wNovel) + self.optState.setSetting("wNotes", wNotes) + self.optState.setSetting("wTOC", wTOC) + self.optState.setSetting("eFormat", eFormat) + self.optState.setSetting("wComments",wComments) + self.optState.setSetting("chFormat", chFormat) + self.optState.setSetting("scFormat", scFormat) + self.optState.setSetting("saveTo", saveTo) + + self.optState.saveSettings() self.close() + return def _doClose(self): @@ -89,16 +115,39 @@ class GuiExportMain(QWidget): FMT_MD = 1 FMT_HTML = 2 FMT_EBOOK = 3 - FMT_FODT = 4 - FMT_PDF = 5 + FMT_ODT = 4 + FMT_TEX = 5 + FMT_HELP = { + FMT_MD : ( + "Exports a standard markdown file. " + "Comments are converted to preformatted text blocks." + ), + FMT_HTML : ( + "Exports a plain html5 file. " + "Comments are converted to preformatted text blocks." + ), + FMT_EBOOK : ( + "Exports an html5 file that can be converted to eBook with Calibre. " + "Comments are not exported in this format." + ), + FMT_ODT : ( + "Exports an open document file that can be read by office applications. " + "Comments are exported as grey text." + ), + FMT_TEX : ( + "Exports a LaTeX file that can be compiled to PDF using for instance PDFLaTeX. " + "Comments are exported as LaTeX comments." + ), + } - def __init__(self, theParent, theProject): + def __init__(self, theParent, theProject, optState): QWidget.__init__(self, theParent) self.theParent = theParent self.theProject = theProject self.theTheme = theParent.theTheme self.outerBox = QGridLayout() + self.optState = optState # Select Files self.guiFiles = QGroupBox("Export Files", self) @@ -106,14 +155,21 @@ class GuiExportMain(QWidget): self.guiFiles.setLayout(self.guiFilesForm) self.expNovel = QCheckBox(self) - self.expNovel.setToolTip("Include all novel files in the exported document") self.expNotes = QCheckBox(self) + self.expTOC = QCheckBox(self) + self.expNovel.setToolTip("Include all novel files in the exported document") self.expNotes.setToolTip("Include all note files in the exported document") + self.expTOC.setToolTip("Generate a Table of Contents (ToC)") + self.expNovel.setChecked(self.optState.wNovel()) + self.expNotes.setChecked(self.optState.wNotes()) + self.expTOC.setChecked(self.optState.wTOC()) self.guiFilesForm.addWidget(QLabel("Novel files"), 0, 0) self.guiFilesForm.addWidget(self.expNovel, 0, 1) self.guiFilesForm.addWidget(QLabel("Note files"), 1, 0) self.guiFilesForm.addWidget(self.expNotes, 1, 1) + self.guiFilesForm.addWidget(QLabel("Contents"), 2, 0) + self.guiFilesForm.addWidget(self.expTOC, 2, 1) # Chapter Settings self.guiChapters = QGroupBox("Chapters", self) @@ -121,7 +177,7 @@ class GuiExportMain(QWidget): self.guiChapters.setLayout(self.guiChaptersForm) self.chapterFormat = QLineEdit() - self.chapterFormat.setText("Chapter %numword%") + self.chapterFormat.setText(self.optState.chFormat()) self.chapterFormat.setToolTip("Available formats: %num%, %numword%, %title%, %label%") self.chapterFormat.setMinimumWidth(250) @@ -133,18 +189,31 @@ class GuiExportMain(QWidget): self.guiOutputForm = QGridLayout(self) self.guiOutput.setLayout(self.guiOutputForm) - self.outputFormat = QComboBox(self) - self.outputFormat.addItem("Markdown", self.FMT_MD) - self.outputFormat.addItem("HTML (Plain)", self.FMT_HTML) - self.outputFormat.addItem("HTML (eBook)", self.FMT_EBOOK) - self.outputFormat.addItem("Open Document", self.FMT_FODT) - self.outputFormat.addItem("PDF (PDFLaTeX)", self.FMT_PDF) - self.outputComments = QCheckBox("include comments", self) + self.outputComments.setChecked(self.optState.wComments()) + + self.outputHelp = QLabel("") + self.outputHelp.setWordWrap(True) + self.outputHelp.setMinimumHeight(55) + self.outputHelp.setAlignment(Qt.AlignTop) + + self.outputFormat = QComboBox(self) + self.outputFormat.addItem("Markdown", self.FMT_MD) + self.outputFormat.addItem("HTML5 (Plain)", self.FMT_HTML) + self.outputFormat.addItem("HTML5 (eBook)", self.FMT_EBOOK) + self.outputFormat.addItem("Open Document", self.FMT_ODT) + self.outputFormat.addItem("LaTeX (PDF)", self.FMT_TEX) + self.outputFormat.currentIndexChanged.connect(self._updateFormatHelp) + + optIdx = self.outputFormat.findData(self.optState.eFormat()) + if optIdx != -1: + self.outputFormat.setCurrentIndex(optIdx) + self._updateFormatHelp(optIdx) self.guiOutputForm.addWidget(QLabel("Export format"), 0, 0) self.guiOutputForm.addWidget(self.outputFormat, 0, 1) self.guiOutputForm.addWidget(self.outputComments, 0, 2) + self.guiOutputForm.addWidget(self.outputHelp, 1, 0, 1, 3) self.guiOutputForm.setColumnStretch(2, 1) # Scene Settings @@ -153,7 +222,7 @@ class GuiExportMain(QWidget): self.guiScenes.setLayout(self.guiScenesForm) self.sceneFormat = QLineEdit() - self.sceneFormat.setText("* * *") + self.sceneFormat.setText(self.optState.scFormat()) self.sceneFormat.setToolTip("Available formats: %title%") self.sceneFormat.setMinimumWidth(100) @@ -165,10 +234,10 @@ class GuiExportMain(QWidget): self.exportToForm = QGridLayout(self) self.exportTo.setLayout(self.exportToForm) - self.exportPath = QLineEdit() + self.exportPath = QLineEdit(self.optState.saveTo()) self.exportGetPath = QPushButton(self.theTheme.getIcon("folder"),"") - # self.exportGetPath.clicked.connect(self._backupFolder) + self.exportGetPath.clicked.connect(self._exportFolder) self.exportToForm.addWidget(QLabel("Save to"), 0, 0) self.exportToForm.addWidget(self.exportPath, 0, 1) @@ -183,9 +252,123 @@ class GuiExportMain(QWidget): self.outerBox.setColumnStretch(0, 1) self.outerBox.setColumnStretch(1, 1) self.outerBox.setColumnStretch(2, 1) - # self.outerBox.setRowStretch(4, 1) self.setLayout(self.outerBox) return + ## + # Internal Functions + ## + + def _updateFormatHelp(self, currIdx): + """Update help text under output format selection. + """ + if currIdx == -1: + self.outputHelp.setText("") + else: + fmtIdx = self.outputFormat.itemData(currIdx) + self.outputHelp.setText("%s" % self.FMT_HELP[fmtIdx]) + + return + + def _exportFolder(self): + + currDir = self.exportPath.text() + if not path.isdir(currDir): + currDir = "" + + dlgOpt = QFileDialog.Options() + dlgOpt |= QFileDialog.ShowDirsOnly + dlgOpt |= QFileDialog.DontUseNativeDialog + newDir = QFileDialog.getExistingDirectory( + self,"Export Directory",currDir,options=dlgOpt + ) + if newDir: + self.exportPath.setText(newDir) + return True + + return False + # END Class GuiExportMain + +class ExportLastState(): + + def __init__(self, theProject): + + self.theProject = theProject + self.theState = { + "wNovel" : True, + "wNotes" : False, + "wTOC" : True, + "eFormat" : 1, + "wComments" : False, + "chFormat" : "Chapter %numword%", + "scFormat" : "* * *", + "saveTo" : "", + } + self.loadSettings() + + return + + def loadSettings(self): + + stateFile = path.join(self.theProject.projMeta, nwFiles.EXPORT_OPT) + if path.isfile(stateFile): + logger.debug("Loading export options file") + try: + with open(stateFile,mode="r") as inFile: + theJson = inFile.read() + self.theState = json.loads(theJson) + except Exception as e: + logger.error("Failed to load export options file") + logger.error(str(e)) + return False + + return True + + def saveSettings(self): + + stateFile = path.join(self.theProject.projMeta, nwFiles.EXPORT_OPT) + logger.debug("Saving export options file") + try: + with open(stateFile,mode="w+") as outFile: + outFile.write(json.dumps(self.theState, indent=2)) + except Exception as e: + logger.error("Failed to save export options file") + logger.error(str(e)) + return False + + return True + + def setSetting(self, setName, setValue): + if setName in self.theState: + self.theState[setName] = setValue + else: + return False + return True + + def wNovel(self): + return checkBool(self.theState["wNovel"],False,False) + + def wNotes(self): + return checkBool(self.theState["wNotes"],False,False) + + def wTOC(self): + return checkBool(self.theState["wTOC"],False,False) + + def eFormat(self): + return checkInt(self.theState["eFormat"],1,False) + + def wComments(self): + return checkBool(self.theState["wComments"],False,False) + + def chFormat(self): + return checkString(self.theState["chFormat"],"Chapter %numword%",False) + + def scFormat(self): + return checkString(self.theState["scFormat"],"* * *",False) + + def saveTo(self): + return checkString(self.theState["saveTo"],"",False) + +# END Class ExportLastState