From dbd1964ff44773e3b858a9d724054140bd648933 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Sun, 13 Oct 2019 12:18:17 +0200
Subject: [PATCH 01/14] Added export dialog class
---
nw/gui/exports.py | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
create mode 100644 nw/gui/exports.py
diff --git a/nw/gui/exports.py b/nw/gui/exports.py
new file mode 100644
index 00000000..1e9babc8
--- /dev/null
+++ b/nw/gui/exports.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+"""novelWriter GUI Export Tools
+
+ novelWriter – GUI Export Tool
+================================
+ Tool for exporting project files to other formats
+
+ File History:
+ Created: 2019-10-13 [0.2.3]
+
+"""
+
+import logging
+import nw
+
+from os import path
+
+from PyQt5.QtWidgets import QDialog
+
+logger = logging.getLogger(__name__)
+
+class GuiExport(QDialog):
+
+# END Class GuiExport
From 32a4e434593842689f2103694c0cec35f7c22fc4 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Sun, 13 Oct 2019 13:31:59 +0200
Subject: [PATCH 02/14] Export dialog working
---
nw/gui/configeditor.py | 2 +-
nw/gui/export.py | 80 ++++++++++++++++++++++++++++++++++++++++++
nw/gui/exports.py | 24 -------------
nw/gui/mainmenu.py | 7 ++++
nw/gui/winmain.py | 7 ++++
5 files changed, 95 insertions(+), 25 deletions(-)
create mode 100644 nw/gui/export.py
delete mode 100644 nw/gui/exports.py
diff --git a/nw/gui/configeditor.py b/nw/gui/configeditor.py
index 69376a78..016040c6 100644
--- a/nw/gui/configeditor.py
+++ b/nw/gui/configeditor.py
@@ -68,7 +68,7 @@ class GuiConfigEditor(QDialog):
self.show()
- logger.debug("ProjectEditor ConfigEditor complete")
+ logger.debug("ConfigEditor initialisation complete")
return
diff --git a/nw/gui/export.py b/nw/gui/export.py
new file mode 100644
index 00000000..86b249ab
--- /dev/null
+++ b/nw/gui/export.py
@@ -0,0 +1,80 @@
+# -*- coding: utf-8 -*-
+"""novelWriter GUI Export Tools
+
+ novelWriter – GUI Export Tool
+================================
+ Tool for exporting project files to other formats
+
+ File History:
+ Created: 2019-10-13 [0.2.3]
+
+"""
+
+import logging
+import nw
+
+from os import path
+
+from PyQt5.QtCore import Qt, QSize
+from PyQt5.QtSvg import QSvgWidget
+from PyQt5.QtWidgets import (
+ QDialog, QHBoxLayout, QVBoxLayout, QWidget, QTabWidget, QDialogButtonBox
+)
+
+logger = logging.getLogger(__name__)
+
+class GuiExport(QDialog):
+
+ def __init__(self, theParent, theProject):
+ QDialog.__init__(self, theParent)
+
+ logger.debug("Initialising GuiExport ...")
+
+ self.mainConf = nw.CONFIG
+ self.theParent = theParent
+ self.theProject = theProject
+
+ self.outerBox = QHBoxLayout()
+ self.innerBox = QVBoxLayout()
+ self.setWindowTitle("Export Project")
+ self.setLayout(self.outerBox)
+
+ self.gradPath = path.abspath(path.join(self.mainConf.appPath,"graphics","gear.svg"))
+ self.svgGradient = QSvgWidget(self.gradPath)
+ self.svgGradient.setFixedSize(QSize(64,64))
+
+ self.theProject.countStatus()
+ self.tabMain = GuiExportMain(self.theParent, self.theProject)
+
+ self.tabWidget = QTabWidget()
+ self.tabWidget.addTab(self.tabMain, "Settings")
+
+ self.outerBox.addWidget(self.svgGradient, 0, Qt.AlignTop)
+ self.outerBox.addLayout(self.innerBox)
+
+ self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
+ # self.buttonBox.accepted.connect(self._doSave)
+ # self.buttonBox.rejected.connect(self._doClose)
+
+ self.innerBox.addWidget(self.tabWidget)
+ self.innerBox.addWidget(self.buttonBox)
+
+ self.show()
+
+ logger.debug("GuiExport initialisation complete")
+
+ return
+
+# END Class GuiExport
+
+class GuiExportMain(QWidget):
+
+ def __init__(self, theParent, theProject):
+ QWidget.__init__(self, theParent)
+
+ self.theParent = theParent
+ self.theProject = theProject
+
+ return
+
+# END Class GuiExportMain
diff --git a/nw/gui/exports.py b/nw/gui/exports.py
deleted file mode 100644
index 1e9babc8..00000000
--- a/nw/gui/exports.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-"""novelWriter GUI Export Tools
-
- novelWriter – GUI Export Tool
-================================
- Tool for exporting project files to other formats
-
- File History:
- Created: 2019-10-13 [0.2.3]
-
-"""
-
-import logging
-import nw
-
-from os import path
-
-from PyQt5.QtWidgets import QDialog
-
-logger = logging.getLogger(__name__)
-
-class GuiExport(QDialog):
-
-# END Class GuiExport
diff --git a/nw/gui/mainmenu.py b/nw/gui/mainmenu.py
index c319dc20..a5d77820 100644
--- a/nw/gui/mainmenu.py
+++ b/nw/gui/mainmenu.py
@@ -192,6 +192,13 @@ class GuiMainMenu(QMenuBar):
menuItem.triggered.connect(self.theParent.editProjectDialog)
self.projMenu.addAction(menuItem)
+ # Project > Export Project
+ menuItem = QAction("Export Project", self)
+ menuItem.setStatusTip("Export project")
+ menuItem.setShortcut("F5")
+ menuItem.triggered.connect(self.theParent.exportProjectDialog)
+ self.projMenu.addAction(menuItem)
+
# Project > Separator
self.projMenu.addSeparator()
diff --git a/nw/gui/winmain.py b/nw/gui/winmain.py
index 8dee5c41..7d3d0aa8 100644
--- a/nw/gui/winmain.py
+++ b/nw/gui/winmain.py
@@ -30,6 +30,7 @@ from nw.gui.searchbar import GuiSearchBar
from nw.gui.mainmenu import GuiMainMenu
from nw.gui.configeditor import GuiConfigEditor
from nw.gui.projecteditor import GuiProjectEditor
+from nw.gui.export import GuiExport
from nw.gui.itemeditor import GuiItemEditor
from nw.gui.statusbar import GuiMainStatus
from nw.gui.timelineview import GuiTimeLineView
@@ -511,6 +512,12 @@ class GuiMain(QMainWindow):
self._setWindowTitle(self.theProject.projName)
return True
+ def exportProjectDialog(self):
+ if self.hasProject:
+ dlgExport = GuiExport(self, self.theProject)
+ dlgExport.exec_()
+ return True
+
def showTimeLineDialog(self):
if self.hasProject:
dlgTLine = GuiTimeLineView(self, self.theProject, self.theIndex)
From e3fadea203f7fcf46f3c371e969e270cad5ec4a3 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Sun, 13 Oct 2019 15:32:29 +0200
Subject: [PATCH 03/14] Added function to translate numbers to words
---
nw/tools/translate.py | 93 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 93 insertions(+)
create mode 100644 nw/tools/translate.py
diff --git a/nw/tools/translate.py b/nw/tools/translate.py
new file mode 100644
index 00000000..33e4885f
--- /dev/null
+++ b/nw/tools/translate.py
@@ -0,0 +1,93 @@
+# -*- coding: utf-8 -*-
+"""novelWriter Translate Tools
+
+ novelWriter – Translate Tools
+===============================
+ Various translate tools
+
+ File History:
+ Created: 2019-10-13 [0.2.3]
+
+"""
+
+import logging
+import nw
+
+from os import path
+
+logger = logging.getLogger(__name__)
+
+def numberToWord(numVal, theLanguage):
+ numWord = ""
+ if theLanguage == "EN":
+ numWord = _numberToWordEN(numVal)
+ else:
+ numWord = _numberToWordEN(numVal)
+ # print("%4d : %s" % (numVal, numWord))
+ return numWord
+
+def _numberToWordEN(numVal):
+
+ numWord = ""
+ oneWord = ""
+ tenWord = ""
+ hunWord = ""
+
+ if numVal == 0:
+ return "Zero"
+
+ oneVal = numVal % 10
+ tenVal = (numVal-oneVal) % 100
+ hunVal = (numVal-tenVal-oneVal) % 1000
+
+ if hunVal == 100: hunWord = "One Hundred"
+ if hunVal == 200: hunWord = "Two Hundred"
+ if hunVal == 300: hunWord = "Three Hundred"
+ if hunVal == 400: hunWord = "Four Hundred"
+ if hunVal == 500: hunWord = "Five Hundred"
+ if hunVal == 600: hunWord = "Six Hundred"
+ if hunVal == 700: hunWord = "Seven Hundred"
+ if hunVal == 800: hunWord = "Eight Hundred"
+ if hunVal == 900: hunWord = "Nine Hundred"
+
+ if tenVal == 20: tenWord = "Twenty"
+ if tenVal == 30: tenWord = "Thirty"
+ if tenVal == 40: tenWord = "Forty"
+ if tenVal == 50: tenWord = "Fifty"
+ if tenVal == 60: tenWord = "Sixty"
+ if tenVal == 70: tenWord = "Seventy"
+ if tenVal == 80: tenWord = "Eighty"
+ if tenVal == 90: tenWord = "Ninety"
+
+ if tenVal == 10:
+ if oneVal == 0: oneWord = "Ten"
+ if oneVal == 1: oneWord = "Eleven"
+ if oneVal == 2: oneWord = "Twelve"
+ if oneVal == 3: oneWord = "Thirteen"
+ if oneVal == 4: oneWord = "Fourteen"
+ if oneVal == 5: oneWord = "Fifteen"
+ if oneVal == 6: oneWord = "Sixteen"
+ if oneVal == 7: oneWord = "Seventeen"
+ if oneVal == 8: oneWord = "Eighteen"
+ if oneVal == 9: oneWord = "Nineteen"
+ numWord = ("%s %s" % (hunWord, oneWord)).strip()
+ else:
+ if oneVal == 0: oneWord = ""
+ if oneVal == 1: oneWord = "One"
+ if oneVal == 2: oneWord = "Two"
+ if oneVal == 3: oneWord = "Three"
+ if oneVal == 4: oneWord = "Four"
+ if oneVal == 5: oneWord = "Five"
+ if oneVal == 6: oneWord = "Six"
+ if oneVal == 7: oneWord = "Seven"
+ if oneVal == 8: oneWord = "Eight"
+ if oneVal == 9: oneWord = "Nine"
+ if tenVal == 0:
+ numWord = ("%s %s" % (hunWord, oneWord)).strip()
+ else:
+ if oneVal == 0:
+ numWord = ("%s %s" % (hunWord, tenWord)).strip()
+ else:
+ numWord = ("%s %s-%s" % (hunWord, tenWord, oneWord)).strip()
+
+ return numWord
From bc06bde05c0932fc9d0090ca4a16a2525c98920d Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Sun, 13 Oct 2019 15:36:57 +0200
Subject: [PATCH 04/14] Added more options to export GUI
---
nw/gui/configeditor.py | 8 ++---
nw/gui/export.py | 69 +++++++++++++++++++++++++++++++++++++++---
2 files changed, 69 insertions(+), 8 deletions(-)
diff --git a/nw/gui/configeditor.py b/nw/gui/configeditor.py
index 016040c6..3a7406ff 100644
--- a/nw/gui/configeditor.py
+++ b/nw/gui/configeditor.py
@@ -111,10 +111,10 @@ class GuiConfigEditGeneral(QWidget):
def __init__(self, theParent):
QWidget.__init__(self, theParent)
- self.mainConf = nw.CONFIG
- self.theParent = theParent
- self.theTheme = theParent.theTheme
- self.outerBox = QGridLayout()
+ self.mainConf = nw.CONFIG
+ self.theParent = theParent
+ self.theTheme = theParent.theTheme
+ self.outerBox = QGridLayout()
# User Interface
self.guiLook = QGroupBox("User Interface", self)
diff --git a/nw/gui/export.py b/nw/gui/export.py
index 86b249ab..41a7e122 100644
--- a/nw/gui/export.py
+++ b/nw/gui/export.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""novelWriter GUI Export Tools
- novelWriter – GUI Export Tool
+ novelWriter – GUI Export Tools
================================
Tool for exporting project files to other formats
@@ -18,9 +18,12 @@ from os import path
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtSvg import QSvgWidget
from PyQt5.QtWidgets import (
- QDialog, QHBoxLayout, QVBoxLayout, QWidget, QTabWidget, QDialogButtonBox
+ QDialog, QHBoxLayout, QVBoxLayout, QWidget, QTabWidget, QDialogButtonBox, QGridLayout,
+ QGroupBox, QCheckBox, QLabel, QComboBox, QLineEdit
)
+from nw.tools.translate import numberToWord
+
logger = logging.getLogger(__name__)
class GuiExport(QDialog):
@@ -61,6 +64,9 @@ class GuiExport(QDialog):
self.show()
+ for n in range(1000):
+ numberToWord(n,"EN")
+
logger.debug("GuiExport initialisation complete")
return
@@ -69,11 +75,66 @@ class GuiExport(QDialog):
class GuiExportMain(QWidget):
+ CHFMT_NUM = 1
+ CHFMT_NUMWORD = 2
+ CHFMT_TITLE = 3
+ CHFMT_LABEL = 4
+ CHFMT_NUMTITLE = 5
+ CHFMT_NUMLABEL = 6
+ CHFMT_CUSTOM = 7
+
def __init__(self, theParent, theProject):
QWidget.__init__(self, theParent)
- self.theParent = theParent
- self.theProject = theProject
+ self.theParent = theParent
+ self.theProject = theProject
+ self.outerBox = QGridLayout()
+
+ # Select Files
+ self.guiFiles = QGroupBox("Export Files", self)
+ self.guiFilesForm = QGridLayout(self)
+ 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.expNotes.setToolTip("Include all note files in the exported document")
+
+ 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)
+
+ # Chapter Settings
+ self.guiChapters = QGroupBox("Chapters", self)
+ self.guiChaptersForm = QGridLayout(self)
+ self.guiChapters.setLayout(self.guiChaptersForm)
+
+ self.chapterFormat = QComboBox(self)
+ self.chapterFormat.addItem("Chapter 1", self.CHFMT_NUM)
+ self.chapterFormat.addItem("Chapter One", self.CHFMT_NUMWORD)
+ self.chapterFormat.addItem("[Title]", self.CHFMT_TITLE)
+ self.chapterFormat.addItem("[Label]", self.CHFMT_LABEL)
+ self.chapterFormat.addItem("1. [Title]", self.CHFMT_NUMTITLE)
+ self.chapterFormat.addItem("1. [Label]", self.CHFMT_NUMLABEL)
+ self.chapterFormat.addItem("Custom", self.CHFMT_CUSTOM)
+
+ self.chapterCustom = QLineEdit()
+ self.chapterCustom.setText("%num%. %title%")
+ self.chapterCustom.setToolTip("Available options: %num%, %numword%, %title%, %label%")
+ self.chapterCustom.setMinimumWidth(200)
+
+ self.guiChaptersForm.addWidget(QLabel("Name format"), 0, 0)
+ self.guiChaptersForm.addWidget(self.chapterFormat, 0, 1)
+ self.guiChaptersForm.addWidget(QLabel("Custom format"), 1, 0)
+ self.guiChaptersForm.addWidget(self.chapterCustom, 1, 1)
+
+ # Assemble
+ self.outerBox.addWidget(self.guiFiles, 0, 0)
+ self.outerBox.addWidget(self.guiChapters, 1, 0)
+ self.outerBox.setColumnStretch(2, 1)
+ self.outerBox.setRowStretch(4, 1)
+ self.setLayout(self.outerBox)
return
From 1d9c4e1e4911cea1f20b8c8b96db2861dcf173fb Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Tue, 15 Oct 2019 19:05:13 +0200
Subject: [PATCH 05/14] Added more elements to the export GUI
---
nw/gui/configeditor.py | 4 ++
nw/gui/export.py | 114 +++++++++++++++++++++++++++++------------
2 files changed, 86 insertions(+), 32 deletions(-)
diff --git a/nw/gui/configeditor.py b/nw/gui/configeditor.py
index 3a7406ff..08b6cefd 100644
--- a/nw/gui/configeditor.py
+++ b/nw/gui/configeditor.py
@@ -72,6 +72,10 @@ class GuiConfigEditor(QDialog):
return
+ ##
+ # Buttons
+ ##
+
def _doSave(self):
logger.verbose("ConfigEditor save button clicked")
diff --git a/nw/gui/export.py b/nw/gui/export.py
index 41a7e122..871e98ee 100644
--- a/nw/gui/export.py
+++ b/nw/gui/export.py
@@ -19,7 +19,7 @@ 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
+ QGroupBox, QCheckBox, QLabel, QComboBox, QLineEdit, QPushButton
)
from nw.tools.translate import numberToWord
@@ -55,39 +55,49 @@ class GuiExport(QDialog):
self.outerBox.addWidget(self.svgGradient, 0, Qt.AlignTop)
self.outerBox.addLayout(self.innerBox)
- self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
- # self.buttonBox.accepted.connect(self._doSave)
- # self.buttonBox.rejected.connect(self._doClose)
+ self.buttonBox = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Cancel)
+ self.buttonBox.accepted.connect(self._doSave)
+ self.buttonBox.rejected.connect(self._doClose)
self.innerBox.addWidget(self.tabWidget)
self.innerBox.addWidget(self.buttonBox)
self.show()
- for n in range(1000):
- numberToWord(n,"EN")
-
logger.debug("GuiExport initialisation complete")
return
+ ##
+ # Buttons
+ ##
+
+ def _doSave(self):
+ logger.verbose("GuiExport save button clicked")
+ self.close()
+ return
+
+ def _doClose(self):
+ logger.verbose("GuiExport close button clicked")
+ self.close()
+ return
+
# END Class GuiExport
class GuiExportMain(QWidget):
- CHFMT_NUM = 1
- CHFMT_NUMWORD = 2
- CHFMT_TITLE = 3
- CHFMT_LABEL = 4
- CHFMT_NUMTITLE = 5
- CHFMT_NUMLABEL = 6
- CHFMT_CUSTOM = 7
+ FMT_MD = 1
+ FMT_HTML = 2
+ FMT_EBOOK = 3
+ FMT_FODT = 4
+ FMT_PDF = 5
def __init__(self, theParent, theProject):
QWidget.__init__(self, theParent)
self.theParent = theParent
self.theProject = theProject
+ self.theTheme = theParent.theTheme
self.outerBox = QGridLayout()
# Select Files
@@ -110,30 +120,70 @@ class GuiExportMain(QWidget):
self.guiChaptersForm = QGridLayout(self)
self.guiChapters.setLayout(self.guiChaptersForm)
- self.chapterFormat = QComboBox(self)
- self.chapterFormat.addItem("Chapter 1", self.CHFMT_NUM)
- self.chapterFormat.addItem("Chapter One", self.CHFMT_NUMWORD)
- self.chapterFormat.addItem("[Title]", self.CHFMT_TITLE)
- self.chapterFormat.addItem("[Label]", self.CHFMT_LABEL)
- self.chapterFormat.addItem("1. [Title]", self.CHFMT_NUMTITLE)
- self.chapterFormat.addItem("1. [Label]", self.CHFMT_NUMLABEL)
- self.chapterFormat.addItem("Custom", self.CHFMT_CUSTOM)
+ self.chapterFormat = QLineEdit()
+ self.chapterFormat.setText("Chapter %numword%")
+ self.chapterFormat.setToolTip("Available formats: %num%, %numword%, %title%, %label%")
+ self.chapterFormat.setMinimumWidth(250)
- self.chapterCustom = QLineEdit()
- self.chapterCustom.setText("%num%. %title%")
- self.chapterCustom.setToolTip("Available options: %num%, %numword%, %title%, %label%")
- self.chapterCustom.setMinimumWidth(200)
+ self.guiChaptersForm.addWidget(QLabel("Format"), 0, 0)
+ self.guiChaptersForm.addWidget(self.chapterFormat, 0, 1)
- self.guiChaptersForm.addWidget(QLabel("Name format"), 0, 0)
- self.guiChaptersForm.addWidget(self.chapterFormat, 0, 1)
- self.guiChaptersForm.addWidget(QLabel("Custom format"), 1, 0)
- self.guiChaptersForm.addWidget(self.chapterCustom, 1, 1)
+ # Output Format
+ self.guiOutput = QGroupBox("Output", self)
+ 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.guiOutputForm.addWidget(QLabel("Export format"), 0, 0)
+ self.guiOutputForm.addWidget(self.outputFormat, 0, 1)
+ self.guiOutputForm.addWidget(self.outputComments, 0, 2)
+ self.guiOutputForm.setColumnStretch(2, 1)
+
+ # Scene Settings
+ self.guiScenes = QGroupBox("Scenes", self)
+ self.guiScenesForm = QGridLayout(self)
+ self.guiScenes.setLayout(self.guiScenesForm)
+
+ self.sceneFormat = QLineEdit()
+ self.sceneFormat.setText("* * *")
+ self.sceneFormat.setToolTip("Available formats: %title%")
+ self.sceneFormat.setMinimumWidth(100)
+
+ self.guiScenesForm.addWidget(QLabel("Format"), 0, 0)
+ self.guiScenesForm.addWidget(self.sceneFormat, 0, 1)
+
+ # Output Path
+ self.exportTo = QGroupBox("Backup", self)
+ self.exportToForm = QGridLayout(self)
+ self.exportTo.setLayout(self.exportToForm)
+
+ self.exportPath = QLineEdit()
+
+ self.exportGetPath = QPushButton(self.theTheme.getIcon("folder"),"")
+ # self.exportGetPath.clicked.connect(self._backupFolder)
+
+ self.exportToForm.addWidget(QLabel("Save to"), 0, 0)
+ self.exportToForm.addWidget(self.exportPath, 0, 1)
+ self.exportToForm.addWidget(self.exportGetPath, 0, 2)
# Assemble
self.outerBox.addWidget(self.guiFiles, 0, 0)
- self.outerBox.addWidget(self.guiChapters, 1, 0)
+ self.outerBox.addWidget(self.guiOutput, 0, 1, 1, 2)
+ self.outerBox.addWidget(self.guiChapters, 1, 0, 1, 2)
+ self.outerBox.addWidget(self.guiScenes, 1, 2)
+ self.outerBox.addWidget(self.exportTo, 2, 0, 1, 3)
+ self.outerBox.setColumnStretch(0, 1)
+ self.outerBox.setColumnStretch(1, 1)
self.outerBox.setColumnStretch(2, 1)
- self.outerBox.setRowStretch(4, 1)
+ # self.outerBox.setRowStretch(4, 1)
self.setLayout(self.outerBox)
return
From a5ad2335de304ccd944bdfee2dddadfbcd4f2716 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Fri, 18 Oct 2019 19:02:28 +0200
Subject: [PATCH 06/14] Export GUI ready
---
nw/constants.py | 1 +
nw/gui/configeditor.py | 1 +
nw/gui/docdetails.py | 2 +-
nw/gui/export.py | 219 +++++++++++++++++++++++++++++++++++++----
4 files changed, 204 insertions(+), 19 deletions(-)
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
From f8878535ba9aae698293aeb644554400752def32 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Fri, 18 Oct 2019 22:09:01 +0200
Subject: [PATCH 07/14] Basic export to plain text now works, but many options
not connected yet
---
nw/convert/textfile.py | 126 ++++++++++++++++++++++++++++++++++++++++
nw/convert/tokenizer.py | 77 ++++++++++++++++++++++++
nw/gui/export.py | 120 +++++++++++++++++++++++++++++---------
3 files changed, 296 insertions(+), 27 deletions(-)
create mode 100644 nw/convert/textfile.py
diff --git a/nw/convert/textfile.py b/nw/convert/textfile.py
new file mode 100644
index 00000000..04cd4b3a
--- /dev/null
+++ b/nw/convert/textfile.py
@@ -0,0 +1,126 @@
+# -*- coding: utf-8 -*-
+"""novelWriter Text File
+
+ novelWriter – Text File
+=========================
+ Writes the project to a plain text file
+
+ File History:
+ Created: 2019-10-18 [0.2.3]
+
+"""
+
+import logging
+import nw
+
+from os import path
+from PyQt5.QtWidgets import QMessageBox
+
+from nw.convert.tokenizer import Tokenizer
+from nw.enum import nwAlert
+
+logger = logging.getLogger(__name__)
+
+class TextFile():
+
+ def __init__(self, theProject, theParent):
+
+ self.mainConf = nw.CONFIG
+ self.theProject = theProject
+ self.theParent = theParent
+ self.fileExt = "txt"
+
+ self.outFile = None
+ self.fileName = ""
+ self.theText = ""
+ self.doComments = False
+ self.doMeta = False
+ self.wordWrap = 80
+ self.winEnding = False
+
+ self.makeAlert = self.theParent.makeAlert
+
+ return
+
+ ##
+ # Setters
+ ##
+
+ def setComments(self, doComments):
+ self.doComments = doComments
+ return
+
+ def setMeta(self, doMeta):
+ self.doMeta = doMeta
+ return
+
+ ##
+ # Core Methods
+ ##
+
+ def openFile(self, saveTo, baseName):
+
+ fileName = "%s.%s" % (baseName.strip(),self.fileExt)
+ filePath = path.join(saveTo,fileName)
+
+ self.fileName = fileName
+
+ if path.isfile(filePath)and self.mainConf.showGUI:
+ msgBox = QMessageBox()
+ msgRes = msgBox.question(
+ self.theParent, "Overwrite", ("File '%s' already exists.
Do you want to overwrite it?" % fileName)
+ )
+ if msgRes != QMessageBox.Yes:
+ return False
+
+ self._doOpenFile(filePath)
+
+ return True
+
+ def closeFile(self):
+ self._doCloseFile()
+ return True
+
+ def addText(self, tHandle):
+
+ logger.verbose("Parsing content of item '%s'" % tHandle)
+
+ aDoc = Tokenizer(self.theProject, self.theParent)
+ aDoc.setText(tHandle)
+ aDoc.doAutoReplace()
+ aDoc.tokenizeText()
+
+ aDoc.setComments(self.doComments)
+ aDoc.setCommands(self.doMeta)
+ aDoc.setWordWrap(self.wordWrap)
+
+ aDoc.doConvert()
+
+ theText = ""
+ if aDoc.theResult is not None:
+ theText = aDoc.theResult
+
+ if self.winEnding:
+ theText = theText.replace("\n","\r\n")
+
+ self.outFile.write(theText)
+
+ return True
+
+ ##
+ # Internal Functions
+ ##
+
+ def _doOpenFile(self, filePath):
+ try:
+ self.outFile = open(filePath,mode="w+")
+ except Exception as e:
+ self.makeAlert(["Failed to open file.",str(e)], nwAlert.ERROR)
+ return False
+ return True
+
+ def _doCloseFile(self):
+ self.outFile.close()
+ return True
+
+# END Class OutFile
diff --git a/nw/convert/tokenizer.py b/nw/convert/tokenizer.py
index 0d62175f..bbb7877b 100644
--- a/nw/convert/tokenizer.py
+++ b/nw/convert/tokenizer.py
@@ -10,6 +10,7 @@
"""
+import textwrap
import logging
import re
import nw
@@ -41,6 +42,25 @@ class Tokenizer():
self.theTokens = None
self.theResult = None
+ self.wordWrap = 80
+ self.doComments = False
+ self.doCommands = False
+
+ return
+
+ def setComments(self, doComments):
+ self.doComments = doComments
+ return
+
+ def setCommands(self, doCommands):
+ self.doCommands = doCommands
+ return
+
+ def setWordWrap(self, wordWrap):
+ if wordWrap >= 0:
+ self.wordWrap = wordWrap
+ else:
+ self.wordWrap = 0
return
def setText(self, theHandle, theText=None):
@@ -129,4 +149,61 @@ class Tokenizer():
return
+ def doConvert(self):
+ """Converts the tokenized text into plain text.
+ """
+
+ self.theResult = ""
+ thisPar = []
+ for tType, tText, tFormat in self.theTokens:
+
+ # First check if we have a comment or plain text, as they need some
+ # extra replacing before we proceed
+ if tType == "comment":
+ tText = "[%s]" % tText
+
+ elif tType == "text":
+ tTemp = tText
+ for xPos, xLen, xFmt in reversed(tFormat):
+ tTemp = tTemp[:xPos]+tTemp[xPos+xLen:]
+ tText = tTemp
+
+ # The text can now be word wrapped, if we have requested this
+ if self.wordWrap > 0:
+ tText = textwrap.fill(tText, width=self.wordWrap)
+
+ # Then the text can receive final formatting before we append it
+ # to the results. We store text bits in a buffer and merge them only
+ # when we find an empty line, indicating a new paragraph
+ if tType == "empty":
+ if len(thisPar) > 0:
+ self.theResult += "%s\n\n" % " ".join(thisPar)
+ thisPar = []
+
+ elif tType == "header1":
+ uLine = "="*min(len(tText),self.wordWrap)
+ self.theResult += "%s\n%s\n\n" % (tText,uLine)
+
+ elif tType == "header2":
+ uLine = "~"*min(len(tText),self.wordWrap)
+ self.theResult += "%s\n%s\n\n" % (tText,uLine)
+
+ elif tType == "header3":
+ uLine = "-"*min(len(tText),self.wordWrap)
+ self.theResult += "%s\n%s\n\n" % (tText,uLine)
+
+ elif tType == "header4":
+ self.theResult += "%s\n\n" % tText
+
+ elif tType == "text":
+ thisPar.append(tText)
+
+ elif tType == "comment" and self.doComments:
+ self.theResult += "%s\n\n" % tText
+
+ elif tType == "command" and self.doCommands:
+ self.theResult += "%s\n\n" % tText
+
+ return
+
# END Class Tokenizer
diff --git a/nw/gui/export.py b/nw/gui/export.py
index 995666f3..0c78211d 100644
--- a/nw/gui/export.py
+++ b/nw/gui/export.py
@@ -11,6 +11,7 @@
"""
import logging
+import time
import json
import nw
@@ -19,13 +20,16 @@ from os import path
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, QFileDialog
+ QDialog, QHBoxLayout, QVBoxLayout, QWidget, QTabWidget, QGridLayout, QGroupBox, QCheckBox,
+ QLabel, QComboBox, QLineEdit, QPushButton, QFileDialog, QProgressBar
)
-from nw.tools.translate import numberToWord
-from nw.common import checkString, checkBool, checkInt
-from nw.constants import nwFiles
+from nw.project.document import NWDoc
+from nw.tools.translate import numberToWord
+from nw.convert.textfile import TextFile
+from nw.common import checkString, checkBool, checkInt
+from nw.constants import nwFiles
+from nw.enum import nwItemType
logger = logging.getLogger(__name__)
@@ -59,13 +63,27 @@ class GuiExport(QDialog):
self.outerBox.addWidget(self.svgGradient, 0, Qt.AlignTop)
self.outerBox.addLayout(self.innerBox)
- self.buttonBox = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Cancel)
- self.buttonBox.accepted.connect(self._doSave)
- self.buttonBox.rejected.connect(self._doClose)
+ self.doExportForm = QGridLayout()
+ self.doExportForm.setContentsMargins(10,5,0,10)
+
+ self.exportButton = QPushButton("Export")
+ self.exportButton.clicked.connect(self._doExport)
+
+ self.closeButton = QPushButton("Close")
+ self.closeButton.clicked.connect(self._doClose)
+
+ self.exportStatus = QLabel("Ready ...")
+ self.exportProgress = QProgressBar(self)
+
+ self.doExportForm.addWidget(self.exportStatus, 0, 0, 1, 3)
+ self.doExportForm.addWidget(self.exportProgress, 1, 0)
+ self.doExportForm.addWidget(self.exportButton, 1, 1)
+ self.doExportForm.addWidget(self.closeButton, 1, 2)
self.innerBox.addWidget(self.tabWidget)
- self.innerBox.addWidget(self.buttonBox)
+ self.innerBox.addLayout(self.doExportForm)
+ self.rejected.connect(self._doClose)
self.show()
logger.debug("GuiExport initialisation complete")
@@ -76,9 +94,56 @@ class GuiExport(QDialog):
# Buttons
##
- def _doSave(self):
+ def _doExport(self):
- logger.verbose("GuiExport save button clicked")
+ logger.verbose("GuiExport export button clicked")
+
+ eFormat = self.tabMain.outputFormat.currentData()
+ wComments = self.tabMain.outputComments.isChecked()
+ saveTo = self.tabMain.exportPath.text()
+
+ outFile = None
+ if eFormat == GuiExportMain.FMT_TXT:
+ outFile = TextFile(self.theProject, self.theParent)
+
+ if outFile is None:
+ return False
+
+ outFile.openFile(saveTo,"testfile")
+ outFile.setComments(wComments)
+
+ nItems = len(self.theProject.treeOrder)
+ self.exportProgress.setMinimum(0)
+ self.exportProgress.setMaximum(nItems)
+ self.exportProgress.setValue(0)
+
+ nDone = 0
+ for tHandle in self.theProject.treeOrder:
+
+ time.sleep(0.1)
+
+ self.exportProgress.setValue(nDone)
+ tItem = self.theProject.getItem(tHandle)
+
+ self.exportStatus.setText("Exporting: %s" % tItem.itemName)
+ logger.verbose("Exporting: %s" % tItem.itemName)
+
+ if tItem is not None and tItem.itemType == nwItemType.FILE:
+ outFile.addText(tHandle)
+
+ nDone += 1
+
+ outFile.closeFile()
+
+ self.exportProgress.setValue(nDone)
+ self.exportStatus.setText("Export to %s complete" % outFile.fileName)
+ logger.verbose("Export to %s complete" % outFile.fileName)
+
+ return
+
+ def _doClose(self):
+
+ logger.verbose("GuiExport close button clicked")
wNovel = self.tabMain.expNovel.isChecked()
wNotes = self.tabMain.expNotes.isChecked()
@@ -103,21 +168,21 @@ class GuiExport(QDialog):
return
- def _doClose(self):
- logger.verbose("GuiExport close button clicked")
- self.close()
- return
-
# END Class GuiExport
class GuiExportMain(QWidget):
- FMT_MD = 1
- FMT_HTML = 2
- FMT_EBOOK = 3
- FMT_ODT = 4
- FMT_TEX = 5
+ FMT_TXT = 1
+ FMT_MD = 2
+ FMT_HTML = 3
+ FMT_EBOOK = 4
+ FMT_ODT = 5
+ FMT_TEX = 6
FMT_HELP = {
+ FMT_TXT : (
+ "Exports a plain text file. "
+ "All formatting is stripped and comments are in square brackets."
+ ),
FMT_MD : (
"Exports a standard markdown file. "
"Comments are converted to preformatted text blocks."
@@ -198,11 +263,12 @@ class GuiExportMain(QWidget):
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.addItem("Plain Text", self.FMT_TXT)
+ # 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())
@@ -300,7 +366,7 @@ class ExportLastState():
"wNovel" : True,
"wNotes" : False,
"wTOC" : True,
- "eFormat" : 1,
+ "eFormat" : 2,
"wComments" : False,
"chFormat" : "Chapter %numword%",
"scFormat" : "* * *",
From d4e74848bcda8659e710e7552460008792c33712 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Fri, 18 Oct 2019 22:41:54 +0200
Subject: [PATCH 08/14] Some improvements and added comments to the converter
classes
---
nw/convert/textfile.py | 13 +++++
nw/convert/tohtml.py | 12 ++---
nw/convert/tokenizer.py | 105 ++++++++++++++++++++++++++--------------
3 files changed, 88 insertions(+), 42 deletions(-)
diff --git a/nw/convert/textfile.py b/nw/convert/textfile.py
index 04cd4b3a..63d5d315 100644
--- a/nw/convert/textfile.py
+++ b/nw/convert/textfile.py
@@ -54,6 +54,13 @@ class TextFile():
self.doMeta = doMeta
return
+ def setWordWrap(self, wordWrap):
+ if wordWrap >= 0:
+ self.wordWrap = wordWrap
+ else:
+ self.wordWrap = 0
+ return
+
##
# Core Methods
##
@@ -112,6 +119,9 @@ class TextFile():
##
def _doOpenFile(self, filePath):
+ """This function does the actual opening of the file, and can be overloaded by a subclass
+ that uses a different file format that requires a different approach.
+ """
try:
self.outFile = open(filePath,mode="w+")
except Exception as e:
@@ -120,6 +130,9 @@ class TextFile():
return True
def _doCloseFile(self):
+ """This function closes a file, and is meant to be overloaded by the subclass for other
+ file formats.
+ """
self.outFile.close()
return True
diff --git a/nw/convert/tohtml.py b/nw/convert/tohtml.py
index c6ec8975..10389bdd 100644
--- a/nw/convert/tohtml.py
+++ b/nw/convert/tohtml.py
@@ -53,19 +53,19 @@ class ToHtml(Tokenizer):
thisPar = []
for tType, tText, tFormat in self.theTokens:
- if tType == "empty":
+ if tType == self.T_EMPTY:
if len(thisPar) > 0:
self.theResult += "
%s
\n" % " ".join(thisPar) thisPar = [] - elif tType == "header1": + elif tType == self.T_HEAD1: self.theResult += "