Merge branch 'dev' into view_details

This commit is contained in:
Veronica K. B. Olsen
2020-05-27 20:22:54 +02:00
19 changed files with 394 additions and 160 deletions
+16
View File
@@ -1,5 +1,21 @@
# novelWriter ChangeLog # novelWriter ChangeLog
## Not Yet Released
**Bugfixes**
* It was possible to have the backup folder set to the same folder as the project, resulting in an infinite loop when `make_archive` was building the zip file. This crash of paths is now checked before moving to the archive step. Issue #240, PR #241.
* Fixed an issue with the Build Novel Project tool on Ubuntu 16.04 LTS where the dialog wouldn't open. PR #246.
**User Interface**
* Renamed the "Generate Preview" button on the "Build Novel Project" tool to "Build Novel Project". You must actually click this to be able to export or print. Issue #237, PR #238.
* Added font family and font size selectors to the "Build Novel Project" tool. You may want a different print font than used in the editor itself. Issue #230, PR #238.
* A margin of the viewport (outside the document) has been added to the document editor and viewer to make room for the document title bar. Previously, the title bar would sit on top of the document top margin, which would sometimes hide text that would otherwise be visible. PR #236.
* Fixed some alignment issue for the status icon on the project tree details panel. Mentioned in #235, PR #239.
* Removed the `Xo` icon for NO_LAYOUT in the project tree details panel. Mentioned in #235, PR #239.
* Added a Details tab to the Project Settings dialog, which also lists the project path. Issue #242, PR #239.
## Version 0.6.1 [2020-05-25] ## Version 0.6.1 [2020-05-25]
**Bugfixes** **Bugfixes**
+3 -3
View File
@@ -424,7 +424,7 @@ class Config:
## Backup ## Backup
cnfSec = "Backup" cnfSec = "Backup"
self.backupPath = self._parseLine( self.backupPath = self._parseLine(
cnfParse, cnfSec, "backuppath", self.CNF_STR, self.backupPath cnfParse, cnfSec, "backuppath", self.CNF_STR, self.backupPath
) )
self.backupOnClose = self._parseLine( self.backupOnClose = self._parseLine(
cnfParse, cnfSec, "backuponclose", self.CNF_BOOL, self.backupOnClose cnfParse, cnfSec, "backuponclose", self.CNF_BOOL, self.backupOnClose
@@ -639,7 +639,7 @@ class Config:
if newPath is None: if newPath is None:
return True return True
if not path.isfile(newPath): if not path.isfile(newPath):
logger.error("Config: File not found. Using default config path instead.") logger.error("File not found, using default config path instead")
return False return False
self.confPath = path.dirname(newPath) self.confPath = path.dirname(newPath)
self.confFile = path.basename(newPath) self.confFile = path.basename(newPath)
@@ -649,7 +649,7 @@ class Config:
if newPath is None: if newPath is None:
return True return True
if not path.isdir(newPath): if not path.isdir(newPath):
logger.error("Config: Path not found. Using default data path instead.") logger.error("Path not found, using default data path instead")
return False return False
self.dataPath = path.abspath(newPath) self.dataPath = path.abspath(newPath)
return True return True
+41 -8
View File
@@ -68,8 +68,8 @@ class NWProject():
self.projChanged = False # The project has unsaved changes self.projChanged = False # The project has unsaved changes
self.projAltered = False # The project has been altered this session self.projAltered = False # The project has been altered this session
self.lockedBy = None # Data on which computer has the project open self.lockedBy = None # Data on which computer has the project open
self.saveCount = None # Meta data: number of saves self.saveCount = 0 # Meta data: number of saves
self.autoCount = None # Meta data: number of automatic saves self.autoCount = 0 # Meta data: number of automatic saves
# Class Settings # Class Settings
self.projPath = None # The full path to where the currently open project is saved self.projPath = None # The full path to where the currently open project is saved
@@ -167,6 +167,7 @@ class NWProject():
"""Create a new project by populating the project tree with a """Create a new project by populating the project tree with a
few starter items. few starter items.
""" """
self.projName = "New Project"
hNovel = self.newRoot("Novel", nwItemClass.NOVEL) hNovel = self.newRoot("Novel", nwItemClass.NOVEL)
hChars = self.newRoot("Characters", nwItemClass.CHARACTER) hChars = self.newRoot("Characters", nwItemClass.CHARACTER)
hWorld = self.newRoot("Plot", nwItemClass.PLOT) hWorld = self.newRoot("Plot", nwItemClass.PLOT)
@@ -526,25 +527,25 @@ class NWProject():
self.theParent.makeAlert(( self.theParent.makeAlert((
"Cannot backup project because no backup path is set. " "Cannot backup project because no backup path is set. "
"Please set a valid backup location in Tools > Preferences." "Please set a valid backup location in Tools > Preferences."
), nwAlert.WARN) ), nwAlert.ERROR)
return False return False
if self.projName is None or self.projName == "": if self.projName is None or self.projName == "":
self.theParent.makeAlert(( self.theParent.makeAlert((
"Cannot backup project because no project name is set. " "Cannot backup project because no project name is set. "
"Please set a Working Title in Project > Project Settings." "Please set a Working Title in Project > Project Settings."
), nwAlert.WARN) ), nwAlert.ERROR)
return False return False
if not path.isdir(self.mainConf.backupPath): if not path.isdir(self.mainConf.backupPath):
self.theParent.makeAlert(( self.theParent.makeAlert((
"Cannot backup project because the backup path does not exist. " "Cannot backup project because the backup path does not exist. "
"Please set a valid backup location in Tools > Preferences." "Please set a valid backup location in Tools > Preferences."
), nwAlert.WARN) ), nwAlert.ERROR)
return False return False
cleanName = self.getFileSafeProjectName() cleanName = self.getFileSafeProjectName()
baseDir = path.join(self.mainConf.backupPath, cleanName) baseDir = path.abspath(path.join(self.mainConf.backupPath, cleanName))
if not path.isdir(baseDir): if not path.isdir(baseDir):
try: try:
mkdir(baseDir) mkdir(baseDir)
@@ -556,6 +557,14 @@ class NWProject():
) )
return False return False
if path.commonpath([self.projPath, baseDir]) == self.projPath:
self.theParent.makeAlert((
"Cannot backup project because the backup path is within the "
"project folder to be backed up. Please choose a different "
"backup path in Tools > Preferences."
), nwAlert.ERROR)
return False
archName = "Backup from %s" % formatTimeStamp(time(), fileSafe=True) archName = "Backup from %s" % formatTimeStamp(time(), fileSafe=True)
baseName = path.join(baseDir, archName) baseName = path.join(baseDir, archName)
@@ -565,7 +574,7 @@ class NWProject():
self._writeLockFile() self._writeLockFile()
if doNotify: if doNotify:
self.theParent.makeAlert( self.theParent.makeAlert(
"Backup archive file written to: '%s.zip'" % path.join(cleanName, archName), "Backup archive file written to: %s.zip" % path.join(cleanName, archName),
nwAlert.INFO nwAlert.INFO
) )
else: else:
@@ -594,7 +603,7 @@ class NWProject():
else: else:
if projPath.startswith("~"): if projPath.startswith("~"):
projPath = path.expanduser(projPath) projPath = path.expanduser(projPath)
self.projPath = projPath self.projPath = path.abspath(projPath)
self.setProjectChanged(True) self.setProjectChanged(True)
return True return True
@@ -1225,6 +1234,30 @@ class NWTree():
self._handleSeed = theSeed self._handleSeed = theSeed
return return
##
# Getters
##
def countTypes(self):
"""Count the number of files, folders and roots in the project.
"""
nRoot = 0
nFolder = 0
nFile = 0
for tHandle in self._treeOrder:
tItem = self.__getitem__(tHandle)
if tItem is None:
continue
elif tItem.itemType == nwItemType.ROOT:
nRoot += 1
elif tItem.itemType == nwItemType.FOLDER:
nFolder += 1
elif tItem.itemType == nwItemType.FILE:
nFile += 1
return nRoot, nFolder, nFile
## ##
# Meta Methods # Meta Methods
## ##
+2 -2
View File
@@ -13,7 +13,7 @@ from nw.gui.dialogs.configeditor import GuiConfigEditor
from nw.gui.dialogs.docmerge import GuiDocMerge from nw.gui.dialogs.docmerge import GuiDocMerge
from nw.gui.dialogs.docsplit import GuiDocSplit from nw.gui.dialogs.docsplit import GuiDocSplit
from nw.gui.dialogs.itemeditor import GuiItemEditor from nw.gui.dialogs.itemeditor import GuiItemEditor
from nw.gui.dialogs.projecteditor import GuiProjectEditor from nw.gui.dialogs.projectsettings import GuiProjectSettings
from nw.gui.dialogs.projectload import GuiProjectLoad from nw.gui.dialogs.projectload import GuiProjectLoad
from nw.gui.dialogs.sessionlog import GuiSessionLogView from nw.gui.dialogs.sessionlog import GuiSessionLogView
@@ -44,7 +44,7 @@ __all__ = [
"GuiDocMerge", "GuiDocMerge",
"GuiDocSplit", "GuiDocSplit",
"GuiItemEditor", "GuiItemEditor",
"GuiProjectEditor", "GuiProjectSettings",
"GuiProjectLoad", "GuiProjectLoad",
"GuiSessionLogView", "GuiSessionLogView",
"GuiDocDetails", "GuiDocDetails",
+5 -5
View File
@@ -97,7 +97,7 @@ class QConfigLayout(QGridLayout):
qLabel = None qLabel = None
raise ValueError("theLabel must be a QLabel") raise ValueError("theLabel must be a QLabel")
qLabel.setContentsMargins(0,4,0,4) qLabel.setContentsMargins(0, 4, 0, 4)
self.addWidget(qLabel, self._nextRow, 0, 1, 2, Qt.AlignLeft) self.addWidget(qLabel, self._nextRow, 0, 1, 2, Qt.AlignLeft)
self.setRowStretch(self._nextRow, 0) self.setRowStretch(self._nextRow, 0)
@@ -141,19 +141,19 @@ class QConfigLayout(QGridLayout):
labelBox.setSpacing(0) labelBox.setSpacing(0)
thisEntry["help"] = qHelp thisEntry["help"] = qHelp
self.addLayout(labelBox, self._nextRow, 0, Qt.AlignLeft) self.addLayout(labelBox, self._nextRow, 0, 1, 1, Qt.AlignLeft | Qt.AlignTop)
else: else:
self.addWidget(qLabel, self._nextRow, 0, Qt.AlignLeft) self.addWidget(qLabel, self._nextRow, 0, 1, 1, Qt.AlignLeft | Qt.AlignTop)
if theUnit is not None: if theUnit is not None:
controlBox = QHBoxLayout() controlBox = QHBoxLayout()
controlBox.addWidget(qWidget, 0, Qt.AlignVCenter) controlBox.addWidget(qWidget, 0, Qt.AlignVCenter)
controlBox.addWidget(QLabel(theUnit), 0, Qt.AlignVCenter) controlBox.addWidget(QLabel(theUnit), 0, Qt.AlignVCenter)
controlBox.setSpacing(8) controlBox.setSpacing(8)
self.addLayout(controlBox, self._nextRow, 1, Qt.AlignRight) self.addLayout(controlBox, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignVCenter)
else: else:
self.addWidget(qWidget, self._nextRow, 1, Qt.AlignRight) self.addWidget(qWidget, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignVCenter)
qLabel.setBuddy(qWidget) qLabel.setBuddy(qWidget)
+99 -50
View File
@@ -38,7 +38,8 @@ from PyQt5.QtGui import (
) )
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QTextBrowser, QPushButton, QLabel, QDialog, QVBoxLayout, QHBoxLayout, QTextBrowser, QPushButton, QLabel,
QLineEdit, QGroupBox, QGridLayout, QProgressBar, QMenu, QAction, QFileDialog QLineEdit, QGroupBox, QGridLayout, QProgressBar, QMenu, QAction,
QFileDialog, QFontComboBox, QSpinBox
) )
from nw.gui.additions import QSwitch from nw.gui.additions import QSwitch
@@ -119,16 +120,16 @@ class GuiBuildNovel(QDialog):
self.fmtSection.setFixedWidth(200) self.fmtSection.setFixedWidth(200)
self.fmtSection.setText(self.theProject.titleFormat["section"]) self.fmtSection.setText(self.theProject.titleFormat["section"])
self.titleForm.addWidget(QLabel("Title"), 0, 0) self.titleForm.addWidget(QLabel("Title"), 0, 0, 1, 1, Qt.AlignLeft)
self.titleForm.addWidget(self.fmtTitle, 0, 1) self.titleForm.addWidget(self.fmtTitle, 0, 1, 1, 1, Qt.AlignRight)
self.titleForm.addWidget(QLabel("Chapter"), 1, 0) self.titleForm.addWidget(QLabel("Chapter"), 1, 0, 1, 1, Qt.AlignLeft)
self.titleForm.addWidget(self.fmtChapter, 1, 1) self.titleForm.addWidget(self.fmtChapter, 1, 1, 1, 1, Qt.AlignRight)
self.titleForm.addWidget(QLabel("Unnumbered"), 2, 0) self.titleForm.addWidget(QLabel("Unnumbered"), 2, 0, 1, 1, Qt.AlignLeft)
self.titleForm.addWidget(self.fmtUnnumbered, 2, 1) self.titleForm.addWidget(self.fmtUnnumbered, 2, 1, 1, 1, Qt.AlignRight)
self.titleForm.addWidget(QLabel("Scene"), 3, 0) self.titleForm.addWidget(QLabel("Scene"), 3, 0, 1, 1, Qt.AlignLeft)
self.titleForm.addWidget(self.fmtScene, 3, 1) self.titleForm.addWidget(self.fmtScene, 3, 1, 1, 1, Qt.AlignRight)
self.titleForm.addWidget(QLabel("Section"), 4, 0) self.titleForm.addWidget(QLabel("Section"), 4, 0, 1, 1, Qt.AlignLeft)
self.titleForm.addWidget(self.fmtSection, 4, 1) self.titleForm.addWidget(self.fmtSection, 4, 1, 1, 1, Qt.AlignRight)
self.titleForm.setColumnStretch(0, 1) self.titleForm.setColumnStretch(0, 1)
self.titleForm.setColumnStretch(1, 0) self.titleForm.setColumnStretch(1, 0)
@@ -139,11 +140,32 @@ class GuiBuildNovel(QDialog):
self.textForm = QGridLayout(self) self.textForm = QGridLayout(self)
self.textGroup.setLayout(self.textForm) self.textGroup.setLayout(self.textForm)
self.justifyText = QSwitch() self.textFont = QFontComboBox()
self.justifyText.setChecked(self.optState.getBool("GuiBuildNovel", "justifyText", False)) self.textFont.setFixedWidth(200)
self.textFont.setCurrentFont(
QFont(self.optState.getString("GuiBuildNovel", "textFont", self.mainConf.textFont))
)
self.textForm.addWidget(QLabel("Justify text"), 0, 0) self.textSize = QSpinBox(self)
self.textForm.addWidget(self.justifyText, 0, 1) self.textSize.setFixedWidth(60)
self.textSize.setMinimum(5)
self.textSize.setMaximum(48)
self.textSize.setSingleStep(1)
self.textSize.setValue(
self.optState.getInt("GuiBuildNovel", "textSize", self.mainConf.textSize)
)
self.justifyText = QSwitch()
self.justifyText.setChecked(
self.optState.getBool("GuiBuildNovel", "justifyText", False)
)
self.textForm.addWidget(QLabel("Font family"), 0, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(self.textFont, 0, 1, 1, 1, Qt.AlignRight)
self.textForm.addWidget(QLabel("Font size"), 1, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(self.textSize, 1, 1, 1, 1, Qt.AlignRight)
self.textForm.addWidget(QLabel("Justify text"), 2, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(self.justifyText, 2, 1, 1, 1, Qt.AlignRight)
self.textForm.setColumnStretch(0, 1) self.textForm.setColumnStretch(0, 1)
self.textForm.setColumnStretch(1, 0) self.textForm.setColumnStretch(1, 0)
@@ -156,17 +178,19 @@ class GuiBuildNovel(QDialog):
self.includeSynopsis = QSwitch() self.includeSynopsis = QSwitch()
self.includeSynopsis.setChecked(self.theProject.titleFormat["withSynopsis"]) self.includeSynopsis.setChecked(self.theProject.titleFormat["withSynopsis"])
self.includeComments = QSwitch() self.includeComments = QSwitch()
self.includeComments.setChecked(self.theProject.titleFormat["withComments"]) self.includeComments.setChecked(self.theProject.titleFormat["withComments"])
self.includeKeywords = QSwitch() self.includeKeywords = QSwitch()
self.includeKeywords.setChecked(self.theProject.titleFormat["withKeywords"]) self.includeKeywords.setChecked(self.theProject.titleFormat["withKeywords"])
self.includeForm.addWidget(QLabel("Include synopsis"), 0, 0) self.includeForm.addWidget(QLabel("Include synopsis"), 0, 0, 1, 1, Qt.AlignLeft)
self.includeForm.addWidget(self.includeSynopsis, 0, 1) self.includeForm.addWidget(self.includeSynopsis, 0, 1, 1, 1, Qt.AlignRight)
self.includeForm.addWidget(QLabel("Include comments"), 1, 0) self.includeForm.addWidget(QLabel("Include comments"), 1, 0, 1, 1, Qt.AlignLeft)
self.includeForm.addWidget(self.includeComments, 1, 1) self.includeForm.addWidget(self.includeComments, 1, 1, 1, 1, Qt.AlignRight)
self.includeForm.addWidget(QLabel("Include keywords"), 2, 0) self.includeForm.addWidget(QLabel("Include keywords"), 2, 0, 1, 1, Qt.AlignLeft)
self.includeForm.addWidget(self.includeKeywords, 2, 1) self.includeForm.addWidget(self.includeKeywords, 2, 1, 1, 1, Qt.AlignRight)
self.includeForm.setColumnStretch(0, 1) self.includeForm.setColumnStretch(0, 1)
self.includeForm.setColumnStretch(1, 0) self.includeForm.setColumnStretch(1, 0)
@@ -178,22 +202,33 @@ class GuiBuildNovel(QDialog):
self.addsGroup.setLayout(self.addsForm) self.addsGroup.setLayout(self.addsForm)
self.novelFiles = QSwitch() self.novelFiles = QSwitch()
self.novelFiles.setChecked(self.optState.getBool("GuiBuildNovel", "addNovel", True)) self.novelFiles.setChecked(
self.noteFiles = QSwitch() self.optState.getBool("GuiBuildNovel", "addNovel", True)
self.noteFiles.setChecked(self.optState.getBool("GuiBuildNovel", "addNotes", False)) )
self.ignoreFlag = QSwitch()
self.ignoreFlag.setChecked(self.optState.getBool("GuiBuildNovel", "ignoreFlag", False))
self.excludeBody = QSwitch()
self.excludeBody.setChecked(self.optState.getBool("GuiBuildNovel", "excludeBody", False))
self.addsForm.addWidget(QLabel("Include novel files"), 0, 0) self.noteFiles = QSwitch()
self.addsForm.addWidget(self.novelFiles, 0, 1) self.noteFiles.setChecked(
self.addsForm.addWidget(QLabel("Include note files"), 1, 0) self.optState.getBool("GuiBuildNovel", "addNotes", False)
self.addsForm.addWidget(self.noteFiles, 1, 1) )
self.addsForm.addWidget(QLabel("Ignore export flag"), 2, 0)
self.addsForm.addWidget(self.ignoreFlag, 2, 1) self.ignoreFlag = QSwitch()
self.addsForm.addWidget(QLabel("Exclude body text"), 3, 0) self.ignoreFlag.setChecked(
self.addsForm.addWidget(self.excludeBody, 3, 1) self.optState.getBool("GuiBuildNovel", "ignoreFlag", False)
)
self.excludeBody = QSwitch()
self.excludeBody.setChecked(
self.optState.getBool("GuiBuildNovel", "excludeBody", False)
)
self.addsForm.addWidget(QLabel("Include novel files"), 0, 0, 1, 1, Qt.AlignLeft)
self.addsForm.addWidget(self.novelFiles, 0, 1, 1, 1, Qt.AlignRight)
self.addsForm.addWidget(QLabel("Include note files"), 1, 0, 1, 1, Qt.AlignLeft)
self.addsForm.addWidget(self.noteFiles, 1, 1, 1, 1, Qt.AlignRight)
self.addsForm.addWidget(QLabel("Ignore export flag"), 2, 0, 1, 1, Qt.AlignLeft)
self.addsForm.addWidget(self.ignoreFlag, 2, 1, 1, 1, Qt.AlignRight)
self.addsForm.addWidget(QLabel("Exclude body text"), 3, 0, 1, 1, Qt.AlignLeft)
self.addsForm.addWidget(self.excludeBody, 3, 1, 1, 1, Qt.AlignRight)
self.addsForm.setColumnStretch(0, 1) self.addsForm.setColumnStretch(0, 1)
self.addsForm.setColumnStretch(1, 0) self.addsForm.setColumnStretch(1, 0)
@@ -202,8 +237,8 @@ class GuiBuildNovel(QDialog):
# ============ # ============
self.buildProgress = QProgressBar() self.buildProgress = QProgressBar()
self.genPreview = QPushButton("Generate Preview") self.buildNovel = QPushButton("Build Novel Project")
self.genPreview.clicked.connect(self._buildPreview) self.buildNovel.clicked.connect(self._buildPreview)
# Action Buttons # Action Buttons
# ============== # ==============
@@ -219,28 +254,28 @@ class GuiBuildNovel(QDialog):
self.saveMenu = QMenu(self) self.saveMenu = QMenu(self)
self.btnSave.setMenu(self.saveMenu) self.btnSave.setMenu(self.saveMenu)
self.saveODT = QAction("Open Document (.odt)") self.saveODT = QAction("Open Document (.odt)", self)
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.savePDF = QAction("Portable Document Format (.pdf)") 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)
self.saveHTM = QAction("%s HTML (.htm)" % nw.__package__) self.saveHTM = QAction("%s HTML (.htm)" % nw.__package__, self)
self.saveHTM.triggered.connect(lambda: self._saveDocument(self.FMT_HTM)) self.saveHTM.triggered.connect(lambda: self._saveDocument(self.FMT_HTM))
self.saveMenu.addAction(self.saveHTM) self.saveMenu.addAction(self.saveHTM)
if self.mainConf.verQtValue >= 51400: if self.mainConf.verQtValue >= 51400:
self.saveMD = QAction("Markdown (.md)") self.saveMD = QAction("Markdown (.md)", self)
self.saveMD.triggered.connect(lambda: self._saveDocument(self.FMT_MD)) self.saveMD.triggered.connect(lambda: self._saveDocument(self.FMT_MD))
self.saveMenu.addAction(self.saveMD) self.saveMenu.addAction(self.saveMD)
self.saveNWD = QAction("novelWriter Markdown (.nwd)") self.saveNWD = QAction("novelWriter Markdown (.nwd)", self)
self.saveNWD.triggered.connect(lambda: self._saveDocument(self.FMT_NWD)) self.saveNWD.triggered.connect(lambda: self._saveDocument(self.FMT_NWD))
self.saveMenu.addAction(self.saveNWD) self.saveMenu.addAction(self.saveNWD)
self.saveTXT = QAction("Plain Text (.txt)") self.saveTXT = QAction("Plain Text (.txt)", self)
self.saveTXT.triggered.connect(lambda: self._saveDocument(self.FMT_TXT)) self.saveTXT.triggered.connect(lambda: self._saveDocument(self.FMT_TXT))
self.saveMenu.addAction(self.saveTXT) self.saveMenu.addAction(self.saveTXT)
@@ -260,7 +295,7 @@ class GuiBuildNovel(QDialog):
self.toolsBox.addWidget(self.addsGroup) self.toolsBox.addWidget(self.addsGroup)
self.toolsBox.addStretch(1) self.toolsBox.addStretch(1)
self.toolsBox.addWidget(self.buildProgress) self.toolsBox.addWidget(self.buildProgress)
self.toolsBox.addWidget(self.genPreview) self.toolsBox.addWidget(self.buildNovel)
self.toolsBox.addSpacing(8) self.toolsBox.addSpacing(8)
self.toolsBox.addLayout(self.buttonForm) self.toolsBox.addLayout(self.buttonForm)
@@ -294,6 +329,8 @@ class GuiBuildNovel(QDialog):
fmtScene = self.fmtScene.text().strip() fmtScene = self.fmtScene.text().strip()
fmtSection = self.fmtSection.text().strip() fmtSection = self.fmtSection.text().strip()
justifyText = self.justifyText.isChecked() justifyText = self.justifyText.isChecked()
textFont = self.textFont.currentFont().family()
textSize = self.textSize.value()
incSynopsis = self.includeSynopsis.isChecked() incSynopsis = self.includeSynopsis.isChecked()
incComments = self.includeComments.isChecked() incComments = self.includeComments.isChecked()
incKeywords = self.includeKeywords.isChecked() incKeywords = self.includeKeywords.isChecked()
@@ -357,6 +394,7 @@ class GuiBuildNovel(QDialog):
self.htmlStyle = makeHtml.getStyleSheet() self.htmlStyle = makeHtml.getStyleSheet()
# Load the preview document with the html data # Load the preview document with the html data
self.docView.setTextFont(textFont, textSize)
self.docView.setJustify(justifyText) self.docView.setJustify(justifyText)
self.docView.setStyleSheet(self.htmlStyle) self.docView.setStyleSheet(self.htmlStyle)
self.docView.setContent(self.htmlText) self.docView.setContent(self.htmlText)
@@ -610,12 +648,14 @@ class GuiBuildNovel(QDialog):
}) })
# GUI Settings # GUI Settings
self.optState.setValue("GuiBuildNovel", "winWidth", self.width()) self.optState.setValue("GuiBuildNovel", "winWidth", self.width())
self.optState.setValue("GuiBuildNovel", "winHeight", self.height()) self.optState.setValue("GuiBuildNovel", "winHeight", self.height())
self.optState.setValue("GuiBuildNovel", "justifyText", self.justifyText.isChecked()) self.optState.setValue("GuiBuildNovel", "justifyText", self.justifyText.isChecked())
self.optState.setValue("GuiBuildNovel", "addNovel", self.novelFiles.isChecked()) self.optState.setValue("GuiBuildNovel", "textFont", self.textFont.currentFont().family())
self.optState.setValue("GuiBuildNovel", "addNotes", self.noteFiles.isChecked()) self.optState.setValue("GuiBuildNovel", "textSize", self.textSize.value())
self.optState.setValue("GuiBuildNovel", "ignoreFlag", self.ignoreFlag.isChecked()) self.optState.setValue("GuiBuildNovel", "addNovel", self.novelFiles.isChecked())
self.optState.setValue("GuiBuildNovel", "addNotes", self.noteFiles.isChecked())
self.optState.setValue("GuiBuildNovel", "ignoreFlag", self.ignoreFlag.isChecked())
self.optState.setValue("GuiBuildNovel", "excludeBody", self.excludeBody.isChecked()) self.optState.setValue("GuiBuildNovel", "excludeBody", self.excludeBody.isChecked())
self.optState.saveSettings() self.optState.saveSettings()
@@ -688,6 +728,15 @@ class GuiBuildNovelDocView(QTextBrowser):
self.qDocument.setDefaultTextOption(theOpt) self.qDocument.setDefaultTextOption(theOpt)
return return
def setTextFont(self, textFont, textSize):
"""Set the text font properties.
"""
theFont = QFont()
theFont.setFamily(textFont)
theFont.setPointSize(textSize)
self.setFont(theFont)
return
def setContent(self, theText): def setContent(self, theText):
"""Set the content, either from text or list of text. """Set the content, either from text or list of text.
""" """
+2 -2
View File
@@ -5,7 +5,7 @@ from nw.gui.dialogs.configeditor import GuiConfigEditor
from nw.gui.dialogs.docmerge import GuiDocMerge from nw.gui.dialogs.docmerge import GuiDocMerge
from nw.gui.dialogs.docsplit import GuiDocSplit from nw.gui.dialogs.docsplit import GuiDocSplit
from nw.gui.dialogs.itemeditor import GuiItemEditor from nw.gui.dialogs.itemeditor import GuiItemEditor
from nw.gui.dialogs.projecteditor import GuiProjectEditor from nw.gui.dialogs.projectsettings import GuiProjectSettings
from nw.gui.dialogs.projectload import GuiProjectLoad from nw.gui.dialogs.projectload import GuiProjectLoad
from nw.gui.dialogs.sessionlog import GuiSessionLogView from nw.gui.dialogs.sessionlog import GuiSessionLogView
@@ -15,7 +15,7 @@ __all__ = [
"GuiDocMerge", "GuiDocMerge",
"GuiDocSplit", "GuiDocSplit",
"GuiItemEditor", "GuiItemEditor",
"GuiProjectEditor", "GuiProjectSettings",
"GuiProjectLoad", "GuiProjectLoad",
"GuiSessionLogView", "GuiSessionLogView",
] ]
@@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""novelWriter GUI Project Editor """novelWriter GUI Project Settings
novelWriter GUI Project Editor novelWriter GUI Project Settings
=================================== ====================================
Class holding the project editor Class holding the project settings dialog
File History: File History:
Created: 2018-09-29 [0.0.1] Created: 2018-09-29 [0.0.1]
@@ -38,16 +38,16 @@ from PyQt5.QtWidgets import (
) )
from nw.constants import nwAlert from nw.constants import nwAlert
from nw.gui.additions import QSwitch, PagedDialog from nw.gui.additions import QSwitch, PagedDialog, QConfigLayout
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class GuiProjectEditor(PagedDialog): class GuiProjectSettings(PagedDialog):
def __init__(self, theParent, theProject): def __init__(self, theParent, theProject):
PagedDialog.__init__(self, theParent) PagedDialog.__init__(self, theParent)
logger.debug("Initialising ProjectEditor ...") logger.debug("Initialising GuiProjectSettings ...")
self.mainConf = nw.CONFIG self.mainConf = nw.CONFIG
self.theParent = theParent self.theParent = theParent
@@ -57,11 +57,13 @@ class GuiProjectEditor(PagedDialog):
self.setWindowTitle("Project Settings") self.setWindowTitle("Project Settings")
self.tabMain = GuiProjectEditMain(self.theParent, self.theProject) self.tabMain = GuiProjectEditMain(self.theParent, self.theProject)
self.tabStatus = GuiProjectEditStatus(self.theParent, self.theProject.statusItems) self.tabMeta = GuiProjectEditMeta(self.theParent, self.theProject)
self.tabImport = GuiProjectEditStatus(self.theParent, self.theProject.importItems) self.tabStatus = GuiProjectEditStatus(self.theParent, self.theProject, True)
self.tabImport = GuiProjectEditStatus(self.theParent, self.theProject, False)
self.tabReplace = GuiProjectEditReplace(self.theParent, self.theProject) self.tabReplace = GuiProjectEditReplace(self.theParent, self.theProject)
self.addTab(self.tabMain, "Settings") self.addTab(self.tabMain, "Settings")
self.addTab(self.tabMeta, "Details")
self.addTab(self.tabStatus, "Status") self.addTab(self.tabStatus, "Status")
self.addTab(self.tabImport, "Importance") self.addTab(self.tabImport, "Importance")
self.addTab(self.tabReplace,"Auto-Replace") self.addTab(self.tabReplace,"Auto-Replace")
@@ -73,12 +75,12 @@ class GuiProjectEditor(PagedDialog):
self.show() self.show()
logger.debug("ProjectEditor initialisation complete") logger.debug("GuiProjectSettings initialisation complete")
return return
def _doSave(self): def _doSave(self):
logger.verbose("ProjectEditor save button clicked") logger.verbose("GuiProjectSettings save button clicked")
projName = self.tabMain.editName.text() projName = self.tabMain.editName.text()
bookTitle = self.tabMain.editTitle.text() bookTitle = self.tabMain.editTitle.text()
@@ -106,69 +108,166 @@ class GuiProjectEditor(PagedDialog):
return return
def _doClose(self): def _doClose(self):
logger.verbose("ProjectEditor close button clicked") logger.verbose("GuiProjectSettings close button clicked")
self.close() self.close()
return return
# END Class GuiProjectEditor # END Class GuiProjectSettings
class GuiProjectEditMain(QWidget): class GuiProjectEditMain(QWidget):
def __init__(self, theParent, theProject): def __init__(self, theParent, theProject):
QWidget.__init__(self, theParent) QWidget.__init__(self, theParent)
self.theParent = theParent self.theParent = theParent
self.theProject = theProject self.theProject = theProject
self.mainForm = QGridLayout()
self.backupBox = QHBoxLayout()
self.editName = QLineEdit() # The Form
self.mainForm = QConfigLayout()
self.mainForm.setHelpTextStyle(self.theParent.theTheme.helpText)
self.setLayout(self.mainForm)
self.mainForm.addGroupLabel("Project Settings")
self.editName = QLineEdit()
self.editName.setMaxLength(200) self.editName.setMaxLength(200)
self.editName.setFixedWidth(250)
self.editName.setText(self.theProject.projName) self.editName.setText(self.theProject.projName)
self.mainForm.addRow(
"Working title",
self.editName,
"Should be set only once."
)
self.editTitle = QLineEdit() self.editTitle = QLineEdit()
self.editTitle.setMaxLength(200) self.editTitle.setMaxLength(200)
self.editTitle.setFixedWidth(250)
self.editTitle.setText(self.theProject.bookTitle) self.editTitle.setText(self.theProject.bookTitle)
self.mainForm.addRow(
"Novel title",
self.editTitle,
"Change whenever you want!"
)
self.editAuthors = QPlainTextEdit() self.editAuthors = QPlainTextEdit()
bookAuthors = "" bookAuthors = ""
for bookAuthor in self.theProject.bookAuthors: for bookAuthor in self.theProject.bookAuthors:
bookAuthors += bookAuthor+"\n" bookAuthors += bookAuthor+"\n"
self.editAuthors.setPlainText(bookAuthors) self.editAuthors.setPlainText(bookAuthors)
self.editAuthors.setMaximumHeight(120) self.editAuthors.setFixedHeight(100)
self.editAuthors.setFixedWidth(250)
self.mainForm.addRow(
"Author(s)",
self.editAuthors,
"One name per line."
)
self.doBackup = QSwitch(self) self.doBackup = QSwitch(self)
self.doBackup.setChecked(not self.theProject.doBackup) self.doBackup.setChecked(not self.theProject.doBackup)
self.backupBox.addStretch(1) self.mainForm.addRow(
self.backupBox.addWidget(QLabel("Disable backup on close")) "No backup on close",
self.backupBox.addWidget(self.doBackup) self.doBackup,
"Overrides main preferences."
self.mainForm.addWidget(QLabel("Working title"), 0, 0, 1, 1, Qt.AlignTop) )
self.mainForm.addWidget(self.editName, 0, 1, 1, 1, Qt.AlignTop)
self.mainForm.addWidget(QLabel("Book title"), 1, 0, 1, 1, Qt.AlignTop)
self.mainForm.addWidget(self.editTitle, 1, 1, 1, 1, Qt.AlignTop)
self.mainForm.addWidget(QLabel("Book authors"), 2, 0, 1, 1, Qt.AlignTop)
self.mainForm.addWidget(self.editAuthors, 2, 1, 1, 1, Qt.AlignTop)
self.mainForm.addLayout(self.backupBox, 3, 0, 1, 2, Qt.AlignTop)
self.setLayout(self.mainForm)
return return
# END Class GuiProjectEditMain # END Class GuiProjectEditMain
class GuiProjectEditStatus(QWidget): class GuiProjectEditMeta(QWidget):
def __init__(self, theParent, theStatus): def __init__(self, theParent, theProject):
QWidget.__init__(self, theParent) QWidget.__init__(self, theParent)
self.theParent = theParent self.theParent = theParent
self.theStatus = theStatus self.theProject = theProject
# The Form
self.mainForm = QGridLayout()
self.setLayout(self.mainForm)
self.headLabel = QLabel("<b>Project Details</b>")
self.nameLabel = QLabel("Working title:")
self.nameLabel.setIndent(8)
self.nameValue = QLabel(self.theProject.projName)
self.nameValue.setWordWrap(True)
self.pathLabel = QLabel("Project path:")
self.pathLabel.setIndent(8)
self.pathValue = QLabel(self.theProject.projPath)
self.pathValue.setWordWrap(True)
self.revLabel = QLabel("Revision count:")
self.revLabel.setIndent(8)
self.revValue = QLabel("{:n}".format(self.theProject.saveCount))
self.statsLabel = QLabel("<b>Project Stats</b>")
nR, nD, nF = self.theProject.projTree.countTypes()
self.nRootLabel = QLabel("Root folders:")
self.nRootLabel.setIndent(8)
self.nRootValue = QLabel("{:n}".format(nR))
self.nDirLabel = QLabel("Folders:")
self.nDirLabel.setIndent(8)
self.nDirValue = QLabel("{:n}".format(nD))
self.nFileLabel = QLabel("Documents:")
self.nFileLabel.setIndent(8)
self.nFileValue = QLabel("{:n}".format(nF))
self.wordsLabel = QLabel("Word count:")
self.wordsLabel.setIndent(8)
self.wordsValue = QLabel("{:n}".format(self.theProject.currWCount))
self.mainForm.addWidget(self.headLabel, 0, 0, 1, 2, Qt.AlignTop)
self.mainForm.addWidget(self.nameLabel, 1, 0, 1, 1, Qt.AlignTop)
self.mainForm.addWidget(self.nameValue, 1, 1, 1, 1, Qt.AlignTop)
self.mainForm.addWidget(self.pathLabel, 2, 0, 1, 1, Qt.AlignTop)
self.mainForm.addWidget(self.pathValue, 2, 1, 1, 1, Qt.AlignTop)
self.mainForm.addWidget(self.revLabel, 3, 0, 1, 1, Qt.AlignTop)
self.mainForm.addWidget(self.revValue, 3, 1, 1, 1, Qt.AlignTop)
self.mainForm.addWidget(self.statsLabel, 4, 0, 1, 2, Qt.AlignTop)
self.mainForm.addWidget(self.nRootLabel, 5, 0, 1, 1, Qt.AlignTop)
self.mainForm.addWidget(self.nRootValue, 5, 1, 1, 1, Qt.AlignTop)
self.mainForm.addWidget(self.nDirLabel, 6, 0, 1, 1, Qt.AlignTop)
self.mainForm.addWidget(self.nDirValue, 6, 1, 1, 1, Qt.AlignTop)
self.mainForm.addWidget(self.nFileLabel, 7, 0, 1, 1, Qt.AlignTop)
self.mainForm.addWidget(self.nFileValue, 7, 1, 1, 1, Qt.AlignTop)
self.mainForm.addWidget(self.wordsLabel, 8, 0, 1, 1, Qt.AlignTop)
self.mainForm.addWidget(self.wordsValue, 8, 1, 1, 1, Qt.AlignTop)
self.mainForm.setVerticalSpacing(6)
self.mainForm.setHorizontalSpacing(12)
self.mainForm.setColumnStretch(0, 0)
self.mainForm.setColumnStretch(1, 1)
self.mainForm.setRowStretch(10, 1)
return
# END Class GuiProjectEditMeta
class GuiProjectEditStatus(QWidget):
def __init__(self, theParent, theProject, isStatus):
QWidget.__init__(self, theParent)
self.theParent = theParent
self.theProject = theProject
if isStatus:
self.theStatus = self.theProject.statusItems
else:
self.theStatus = self.theProject.importItems
self.colData = [] self.colData = []
self.colCounts = [] self.colCounts = []
self.colChanged = False self.colChanged = False
self.selColour = None self.selColour = None
self.outerBox = QVBoxLayout()
self.mainBox = QHBoxLayout() self.mainBox = QHBoxLayout()
self.mainForm = QVBoxLayout() self.mainForm = QVBoxLayout()
@@ -208,7 +307,13 @@ class GuiProjectEditStatus(QWidget):
self.mainBox.addWidget(self.listBox) self.mainBox.addWidget(self.listBox)
self.mainBox.addLayout(self.mainForm) self.mainBox.addLayout(self.mainForm)
self.setLayout(self.mainBox) if isStatus:
self.outerBox.addWidget(QLabel("<b>Novel File Status Levels</b>"))
else:
self.outerBox.addWidget(QLabel("<b>Note File Importance Levels</b>"))
self.outerBox.addLayout(self.mainBox)
self.setLayout(self.outerBox)
return return
@@ -374,6 +479,7 @@ class GuiProjectEditReplace(QWidget):
self.bottomBox.addWidget(self.addButton) self.bottomBox.addWidget(self.addButton)
self.bottomBox.addWidget(self.delButton) self.bottomBox.addWidget(self.delButton)
self.outerBox.addWidget(QLabel("<b>Text Replace List for Preview and Export</b>"))
self.outerBox.addWidget(self.listBox) self.outerBox.addWidget(self.listBox)
self.outerBox.addLayout(self.bottomBox) self.outerBox.addLayout(self.bottomBox)
self.setLayout(self.outerBox) self.setLayout(self.outerBox)
+25 -20
View File
@@ -32,7 +32,9 @@ from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QFrame, QGridLayout, QLabel from PyQt5.QtWidgets import QFrame, QGridLayout, QLabel
from nw.constants import nwLabels, nwItemClass, nwItemType, nwUnicode from nw.constants import (
nwLabels, nwItemClass, nwItemType, nwItemLayout, nwUnicode
)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -143,27 +145,27 @@ class GuiDocDetails(QFrame):
self.pCountData.setAlignment(Qt.AlignRight) self.pCountData.setAlignment(Qt.AlignRight)
# Assemble # Assemble
self.mainBox.addWidget(self.labelName, 0, 0, 1, 1, Qt.AlignTop) self.mainBox.addWidget(self.labelName, 0, 0, 1, 1)
self.mainBox.addWidget(self.labelFlag, 0, 1, 1, 1, Qt.AlignTop) self.mainBox.addWidget(self.labelFlag, 0, 1, 1, 1)
self.mainBox.addWidget(self.labelData, 0, 2, 1, 3, Qt.AlignTop) self.mainBox.addWidget(self.labelData, 0, 2, 1, 3)
self.mainBox.addWidget(self.statusName, 1, 0, 1, 1, Qt.AlignTop) self.mainBox.addWidget(self.statusName, 1, 0, 1, 1)
self.mainBox.addWidget(self.statusFlag, 1, 1, 1, 1, Qt.AlignTop) self.mainBox.addWidget(self.statusFlag, 1, 1, 1, 1)
self.mainBox.addWidget(self.statusData, 1, 2, 1, 1, Qt.AlignTop) self.mainBox.addWidget(self.statusData, 1, 2, 1, 1)
self.mainBox.addWidget(self.cCountName, 1, 3, 1, 1, Qt.AlignTop) self.mainBox.addWidget(self.cCountName, 1, 3, 1, 1)
self.mainBox.addWidget(self.cCountData, 1, 4, 1, 1, Qt.AlignTop) self.mainBox.addWidget(self.cCountData, 1, 4, 1, 1)
self.mainBox.addWidget(self.className, 2, 0, 1, 1, Qt.AlignTop) self.mainBox.addWidget(self.className, 2, 0, 1, 1)
self.mainBox.addWidget(self.classFlag, 2, 1, 1, 1, Qt.AlignTop) self.mainBox.addWidget(self.classFlag, 2, 1, 1, 1)
self.mainBox.addWidget(self.classData, 2, 2, 1, 1, Qt.AlignTop) self.mainBox.addWidget(self.classData, 2, 2, 1, 1)
self.mainBox.addWidget(self.wCountName, 2, 3, 1, 1, Qt.AlignTop) self.mainBox.addWidget(self.wCountName, 2, 3, 1, 1)
self.mainBox.addWidget(self.wCountData, 2, 4, 1, 1, Qt.AlignTop) self.mainBox.addWidget(self.wCountData, 2, 4, 1, 1)
self.mainBox.addWidget(self.layoutName, 3, 0, 1, 1, Qt.AlignTop) self.mainBox.addWidget(self.layoutName, 3, 0, 1, 1)
self.mainBox.addWidget(self.layoutFlag, 3, 1, 1, 1, Qt.AlignTop) self.mainBox.addWidget(self.layoutFlag, 3, 1, 1, 1)
self.mainBox.addWidget(self.layoutData, 3, 2, 1, 1, Qt.AlignTop) self.mainBox.addWidget(self.layoutData, 3, 2, 1, 1)
self.mainBox.addWidget(self.pCountName, 3, 3, 1, 1, Qt.AlignTop) self.mainBox.addWidget(self.pCountName, 3, 3, 1, 1)
self.mainBox.addWidget(self.pCountData, 3, 4, 1, 1, Qt.AlignTop) self.mainBox.addWidget(self.pCountData, 3, 4, 1, 1)
self.mainBox.setColumnStretch(0,0) self.mainBox.setColumnStretch(0,0)
self.mainBox.setColumnStretch(1,0) self.mainBox.setColumnStretch(1,0)
@@ -221,7 +223,10 @@ class GuiDocDetails(QFrame):
self.labelFlag.setText(exportFlag) self.labelFlag.setText(exportFlag)
self.statusFlag.setPixmap(flagIcon.pixmap(10, 10)) self.statusFlag.setPixmap(flagIcon.pixmap(10, 10))
self.classFlag.setText(nwLabels.CLASS_FLAG[nwItem.itemClass]) self.classFlag.setText(nwLabels.CLASS_FLAG[nwItem.itemClass])
self.layoutFlag.setText(nwLabels.LAYOUT_FLAG[nwItem.itemLayout]) if nwItem.itemLayout == nwItemLayout.NO_LAYOUT:
self.layoutFlag.setText("-")
else:
self.layoutFlag.setText(nwLabels.LAYOUT_FLAG[nwItem.itemLayout])
self.labelData.setText(theLabel) self.labelData.setText(theLabel)
self.statusData.setText(nwItem.itemStatus) self.statusData.setText(nwItem.itemStatus)
+10 -4
View File
@@ -85,7 +85,8 @@ class GuiDocEditor(QTextEdit):
# Document Title # Document Title
self.docTitle = GuiDocTitleBar(self, self.theProject) self.docTitle = GuiDocTitleBar(self, self.theProject)
self.docTitle.setGeometry(0,0,self.docTitle.width(),self.docTitle.height()) self.docTitle.setGeometry(0, 0, self.docTitle.width(), self.docTitle.height())
self.setViewportMargins(0, self.docTitle.height(), 0, 0)
# Syntax # Syntax
self.hLight = GuiDocHighlighter(self.qDocument, self.theParent) self.hLight = GuiDocHighlighter(self.qDocument, self.theParent)
@@ -227,7 +228,6 @@ class GuiDocEditor(QTextEdit):
tHandle = self.theHandle tHandle = self.theHandle
self.clearEditor() self.clearEditor()
self.loadText(tHandle, showStatus=False) self.loadText(tHandle, showStatus=False)
self.updateDocMargins()
return return
def loadText(self, tHandle, tLine=None, showStatus=True): def loadText(self, tHandle, tLine=None, showStatus=True):
@@ -288,6 +288,7 @@ class GuiDocEditor(QTextEdit):
""" """
self.setPlainText(theText) self.setPlainText(theText)
self.setDocumentChanged(True) self.setDocumentChanged(True)
self.updateDocMargins()
return return
def saveText(self): def saveText(self):
@@ -336,13 +337,17 @@ class GuiDocEditor(QTextEdit):
tB = self.lineWidth() tB = self.lineWidth()
tW = self.width() - 2*tB tW = self.width() - 2*tB
tH = self.docTitle.height() tH = self.docTitle.height()
tT = self.mainConf.textMargin - tH
self.docTitle.setGeometry(tB, tB, tW, tH) self.docTitle.setGeometry(tB, tB, tW, tH)
self.setViewportMargins(0, tH, 0, 0)
docFormat = self.qDocument.rootFrame().frameFormat() docFormat = self.qDocument.rootFrame().frameFormat()
docFormat.setLeftMargin(tM) docFormat.setLeftMargin(tM)
docFormat.setRightMargin(tM) docFormat.setRightMargin(tM)
if docFormat.topMargin() < tH: if tT > 0:
docFormat.setTopMargin(tH + 2) docFormat.setTopMargin(tT)
else:
docFormat.setTopMargin(0)
# Updating root frame triggers a QTextDocument->contentsChange # Updating root frame triggers a QTextDocument->contentsChange
# signal, which we do not want as it re-runs the syntax # signal, which we do not want as it re-runs the syntax
@@ -365,6 +370,7 @@ class GuiDocEditor(QTextEdit):
""" """
if tHandle == self.theHandle: if tHandle == self.theHandle:
self.docTitle.setTitleFromHandle(self.theHandle) self.docTitle.setTitleFromHandle(self.theHandle)
self.updateDocMargins()
return return
## ##
+29 -11
View File
@@ -59,7 +59,8 @@ class GuiDocViewer(QTextBrowser):
# Document Title # Document Title
self.docTitle = GuiDocTitleBar(self, self.theProject) self.docTitle = GuiDocTitleBar(self, self.theProject)
self.docTitle.setGeometry(0,0,self.docTitle.width(),self.docTitle.height()) self.docTitle.setGeometry(0, 0, self.docTitle.width(), self.docTitle.height())
self.setViewportMargins(0, self.docTitle.height(), 0, 0)
theOpt = QTextOption() theOpt = QTextOption()
if self.mainConf.doJustify: if self.mainConf.doJustify:
@@ -145,6 +146,7 @@ class GuiDocViewer(QTextBrowser):
self.theHandle = tHandle self.theHandle = tHandle
self.theProject.setLastViewed(tHandle) self.theProject.setLastViewed(tHandle)
self.docTitle.setTitleFromHandle(self.theHandle) self.docTitle.setTitleFromHandle(self.theHandle)
self.updateDocMargins()
# Make sure the main GUI knows we changed the content # Make sure the main GUI knows we changed the content
self.theParent.viewMeta.refreshReferences(tHandle) self.theParent.viewMeta.refreshReferences(tHandle)
@@ -206,12 +208,37 @@ class GuiDocViewer(QTextBrowser):
self.setSource(QUrl(navLink)) self.setSource(QUrl(navLink))
return True return True
def updateDocMargins(self):
"""Automatically adjust the margins so the text is centred if
Config.textFixedW is enabled or we're in Zen mode. Otherwise,
just ensure the margins are set correctly.
"""
tB = self.lineWidth()
tW = self.width() - 2*tB
tH = self.docTitle.height()
tT = self.mainConf.textMargin - tH
self.docTitle.setGeometry(tB, tB, tW, tH)
self.setViewportMargins(0, tH, 0, 0)
docFormat = self.qDocument.rootFrame().frameFormat()
if tT > 0:
docFormat.setTopMargin(tT)
else:
docFormat.setTopMargin(0)
self.qDocument.blockSignals(True)
self.qDocument.rootFrame().setFrameFormat(docFormat)
self.qDocument.blockSignals(False)
return
def updateDocTitle(self, tHandle): def updateDocTitle(self, tHandle):
"""Called when an item label is changed to check if the document """Called when an item label is changed to check if the document
title bar needs updating, title bar needs updating,
""" """
if tHandle == self.theHandle: if tHandle == self.theHandle:
self.docTitle.setTitleFromHandle(self.theHandle) self.docTitle.setTitleFromHandle(self.theHandle)
self.updateDocMargins()
return return
## ##
@@ -249,16 +276,7 @@ class GuiDocViewer(QTextBrowser):
"""Make sure the document title is the same width as the window. """Make sure the document title is the same width as the window.
""" """
QTextBrowser.resizeEvent(self, theEvent) QTextBrowser.resizeEvent(self, theEvent)
self.updateDocMargins()
tB = self.lineWidth()
tW = self.width() - 2*tB
tH = self.docTitle.height()
self.docTitle.setGeometry(tB, tB, tW, tH)
docFormat = self.qDocument.rootFrame().frameFormat()
if docFormat.topMargin() < tH:
docFormat.setTopMargin(tH + 2)
return return
## ##
+2 -2
View File
@@ -42,7 +42,7 @@ from PyQt5.QtWidgets import (
from nw.gui import ( from nw.gui import (
GuiMainMenu, GuiMainStatus, GuiTheme, GuiDocTree, GuiDocEditor, GuiMainMenu, GuiMainStatus, GuiTheme, GuiDocTree, GuiDocEditor,
GuiDocViewer, GuiDocDetails, GuiSearchBar, GuiNoticeBar, GuiDocViewDetails, GuiDocViewer, GuiDocDetails, GuiSearchBar, GuiNoticeBar, GuiDocViewDetails,
GuiConfigEditor, GuiProjectEditor, GuiItemEditor, GuiProjectOutline, GuiConfigEditor, GuiProjectSettings, GuiItemEditor, GuiProjectOutline,
GuiSessionLogView, GuiDocMerge, GuiDocSplit, GuiProjectLoad, GuiBuildNovel GuiSessionLogView, GuiDocMerge, GuiDocSplit, GuiProjectLoad, GuiBuildNovel
) )
from nw.core import NWProject, NWDoc, NWIndex from nw.core import NWProject, NWDoc, NWIndex
@@ -751,7 +751,7 @@ class GuiMain(QMainWindow):
"""Open the project settings dialog. """Open the project settings dialog.
""" """
if self.hasProject: if self.hasProject:
dlgProj = GuiProjectEditor(self, self.theProject) dlgProj = GuiProjectSettings(self, self.theProject)
dlgProj.exec_() dlgProj.exec_()
self._setWindowTitle(self.theProject.projName) self._setWindowTitle(self.theProject.projName)
return True return True
+2 -2
View File
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="0.5" fileVersion="1.0" saveCount="2" autoCount="0" timeStamp="2020-05-10 23:17:36"> <novelWriterXML appVersion="0.6.1" hexVersion="0x000601f0" fileVersion="1.0" saveCount="2" autoCount="0" timeStamp="2020-05-27 18:25:48">
<project> <project>
<name></name> <name>New Project</name>
<title></title> <title></title>
<backup>True</backup> <backup>True</backup>
</project> </project>
+2 -2
View File
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="0.5" fileVersion="1.0" saveCount="4" autoCount="0" timeStamp="2020-05-10 23:18:06"> <novelWriterXML appVersion="0.6.1" hexVersion="0x000601f0" fileVersion="1.0" saveCount="4" autoCount="0" timeStamp="2020-05-27 18:27:20">
<project> <project>
<name></name> <name>New Project</name>
<title></title> <title></title>
<backup>True</backup> <backup>True</backup>
</project> </project>
+2 -2
View File
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="0.5" fileVersion="1.0" saveCount="2" autoCount="0" timeStamp="2020-05-10 23:19:44"> <novelWriterXML appVersion="0.6.1" hexVersion="0x000601f0" fileVersion="1.0" saveCount="2" autoCount="0" timeStamp="2020-05-27 18:30:26">
<project> <project>
<name></name> <name>New Project</name>
<title></title> <title></title>
<backup>True</backup> <backup>True</backup>
</project> </project>
+2 -2
View File
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="0.5" fileVersion="1.0" saveCount="1" autoCount="0" timeStamp="2020-05-10 23:16:14"> <novelWriterXML appVersion="0.6.1" hexVersion="0x000601f0" fileVersion="1.0" saveCount="1" autoCount="0" timeStamp="2020-05-27 18:23:46">
<project> <project>
<name></name> <name>New Project</name>
<title></title> <title></title>
<backup>True</backup> <backup>True</backup>
</project> </project>
+2 -2
View File
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="0.5" fileVersion="1.0" saveCount="4" autoCount="0" timeStamp="2020-05-10 23:16:52"> <novelWriterXML appVersion="0.6.1" hexVersion="0x000601f0" fileVersion="1.0" saveCount="4" autoCount="0" timeStamp="2020-05-27 18:24:35">
<project> <project>
<name></name> <name>New Project</name>
<title></title> <title></title>
<backup>True</backup> <backup>True</backup>
</project> </project>
+2 -2
View File
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="0.5.1" hexVersion="0x000501f0" fileVersion="1.0" saveCount="5" autoCount="0" timeStamp="2020-05-18 23:33:37"> <novelWriterXML appVersion="0.6.1" hexVersion="0x000601f0" fileVersion="1.0" saveCount="5" autoCount="0" timeStamp="2020-05-27 18:24:56">
<project> <project>
<name></name> <name>New Project</name>
<title></title> <title></title>
<backup>True</backup> <backup>True</backup>
</project> </project>
+6 -5
View File
@@ -8,8 +8,8 @@ from nwtools import *
from os import path, unlink from os import path, unlink
from PyQt5.QtCore import Qt from PyQt5.QtCore import Qt
from nw.gui.dialogs.projecteditor import GuiProjectEditor from nw.gui.dialogs.projectsettings import GuiProjectSettings
from nw.gui.dialogs.itemeditor import GuiItemEditor from nw.gui.dialogs.itemeditor import GuiItemEditor
from nw.constants import * from nw.constants import *
@@ -61,7 +61,7 @@ def testMainWindows(qtbot, nwTempGUI, nwRef, nwTemp):
assert nwGUI.theProject.projPath == nwTempGUI assert nwGUI.theProject.projPath == nwTempGUI
assert nwGUI.theProject.projMeta == path.join(nwTempGUI,"meta") assert nwGUI.theProject.projMeta == path.join(nwTempGUI,"meta")
assert nwGUI.theProject.projFile == "nwProject.nwx" assert nwGUI.theProject.projFile == "nwProject.nwx"
assert nwGUI.theProject.projName == "" assert nwGUI.theProject.projName == "New Project"
assert nwGUI.theProject.bookTitle == "" assert nwGUI.theProject.bookTitle == ""
assert len(nwGUI.theProject.bookAuthors) == 0 assert len(nwGUI.theProject.bookAuthors) == 0
assert nwGUI.theProject.spellCheck == False assert nwGUI.theProject.spellCheck == False
@@ -262,9 +262,10 @@ def testProjectEditor(qtbot, nwTempGUI, nwRef, nwTemp):
assert nwGUI.newProject(nwTempGUI, True) assert nwGUI.newProject(nwTempGUI, True)
nwGUI.mainConf.backupPath = nwTempGUI nwGUI.mainConf.backupPath = nwTempGUI
projEdit = GuiProjectEditor(nwGUI, nwGUI.theProject) projEdit = GuiProjectSettings(nwGUI, nwGUI.theProject)
qtbot.addWidget(projEdit) qtbot.addWidget(projEdit)
projEdit.tabMain.editName.setText("")
for c in "Project Name": for c in "Project Name":
qtbot.keyClick(projEdit.tabMain.editName, c, delay=keyDelay) qtbot.keyClick(projEdit.tabMain.editName, c, delay=keyDelay)
for c in "Project Title": for c in "Project Title":
@@ -314,7 +315,7 @@ def testProjectEditor(qtbot, nwTempGUI, nwRef, nwTemp):
projEdit._doSave() projEdit._doSave()
# Open again, and check project settings # Open again, and check project settings
projEdit = GuiProjectEditor(nwGUI, nwGUI.theProject) projEdit = GuiProjectSettings(nwGUI, nwGUI.theProject)
qtbot.addWidget(projEdit) qtbot.addWidget(projEdit)
assert projEdit.tabMain.editName.text() == "Project Name" assert projEdit.tabMain.editName.text() == "Project Name"
assert projEdit.tabMain.editTitle.text() == "Project Title" assert projEdit.tabMain.editTitle.text() == "Project Title"