Merge branch 'dev' into view_details
This commit is contained in:
@@ -1,5 +1,21 @@
|
||||
# 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]
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
+3
-3
@@ -424,7 +424,7 @@ class Config:
|
||||
## Backup
|
||||
cnfSec = "Backup"
|
||||
self.backupPath = self._parseLine(
|
||||
cnfParse, cnfSec, "backuppath", self.CNF_STR, self.backupPath
|
||||
cnfParse, cnfSec, "backuppath", self.CNF_STR, self.backupPath
|
||||
)
|
||||
self.backupOnClose = self._parseLine(
|
||||
cnfParse, cnfSec, "backuponclose", self.CNF_BOOL, self.backupOnClose
|
||||
@@ -639,7 +639,7 @@ class Config:
|
||||
if newPath is None:
|
||||
return True
|
||||
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
|
||||
self.confPath = path.dirname(newPath)
|
||||
self.confFile = path.basename(newPath)
|
||||
@@ -649,7 +649,7 @@ class Config:
|
||||
if newPath is None:
|
||||
return True
|
||||
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
|
||||
self.dataPath = path.abspath(newPath)
|
||||
return True
|
||||
|
||||
+41
-8
@@ -68,8 +68,8 @@ class NWProject():
|
||||
self.projChanged = False # The project has unsaved changes
|
||||
self.projAltered = False # The project has been altered this session
|
||||
self.lockedBy = None # Data on which computer has the project open
|
||||
self.saveCount = None # Meta data: number of saves
|
||||
self.autoCount = None # Meta data: number of automatic saves
|
||||
self.saveCount = 0 # Meta data: number of saves
|
||||
self.autoCount = 0 # Meta data: number of automatic saves
|
||||
|
||||
# Class Settings
|
||||
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
|
||||
few starter items.
|
||||
"""
|
||||
self.projName = "New Project"
|
||||
hNovel = self.newRoot("Novel", nwItemClass.NOVEL)
|
||||
hChars = self.newRoot("Characters", nwItemClass.CHARACTER)
|
||||
hWorld = self.newRoot("Plot", nwItemClass.PLOT)
|
||||
@@ -526,25 +527,25 @@ class NWProject():
|
||||
self.theParent.makeAlert((
|
||||
"Cannot backup project because no backup path is set. "
|
||||
"Please set a valid backup location in Tools > Preferences."
|
||||
), nwAlert.WARN)
|
||||
), nwAlert.ERROR)
|
||||
return False
|
||||
|
||||
if self.projName is None or self.projName == "":
|
||||
self.theParent.makeAlert((
|
||||
"Cannot backup project because no project name is set. "
|
||||
"Please set a Working Title in Project > Project Settings."
|
||||
), nwAlert.WARN)
|
||||
), nwAlert.ERROR)
|
||||
return False
|
||||
|
||||
if not path.isdir(self.mainConf.backupPath):
|
||||
self.theParent.makeAlert((
|
||||
"Cannot backup project because the backup path does not exist. "
|
||||
"Please set a valid backup location in Tools > Preferences."
|
||||
), nwAlert.WARN)
|
||||
), nwAlert.ERROR)
|
||||
return False
|
||||
|
||||
cleanName = self.getFileSafeProjectName()
|
||||
baseDir = path.join(self.mainConf.backupPath, cleanName)
|
||||
baseDir = path.abspath(path.join(self.mainConf.backupPath, cleanName))
|
||||
if not path.isdir(baseDir):
|
||||
try:
|
||||
mkdir(baseDir)
|
||||
@@ -556,6 +557,14 @@ class NWProject():
|
||||
)
|
||||
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)
|
||||
baseName = path.join(baseDir, archName)
|
||||
|
||||
@@ -565,7 +574,7 @@ class NWProject():
|
||||
self._writeLockFile()
|
||||
if doNotify:
|
||||
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
|
||||
)
|
||||
else:
|
||||
@@ -594,7 +603,7 @@ class NWProject():
|
||||
else:
|
||||
if projPath.startswith("~"):
|
||||
projPath = path.expanduser(projPath)
|
||||
self.projPath = projPath
|
||||
self.projPath = path.abspath(projPath)
|
||||
self.setProjectChanged(True)
|
||||
return True
|
||||
|
||||
@@ -1225,6 +1234,30 @@ class NWTree():
|
||||
self._handleSeed = theSeed
|
||||
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
|
||||
##
|
||||
|
||||
+2
-2
@@ -13,7 +13,7 @@ from nw.gui.dialogs.configeditor import GuiConfigEditor
|
||||
from nw.gui.dialogs.docmerge import GuiDocMerge
|
||||
from nw.gui.dialogs.docsplit import GuiDocSplit
|
||||
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.sessionlog import GuiSessionLogView
|
||||
|
||||
@@ -44,7 +44,7 @@ __all__ = [
|
||||
"GuiDocMerge",
|
||||
"GuiDocSplit",
|
||||
"GuiItemEditor",
|
||||
"GuiProjectEditor",
|
||||
"GuiProjectSettings",
|
||||
"GuiProjectLoad",
|
||||
"GuiSessionLogView",
|
||||
"GuiDocDetails",
|
||||
|
||||
@@ -97,7 +97,7 @@ class QConfigLayout(QGridLayout):
|
||||
qLabel = None
|
||||
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.setRowStretch(self._nextRow, 0)
|
||||
@@ -141,19 +141,19 @@ class QConfigLayout(QGridLayout):
|
||||
labelBox.setSpacing(0)
|
||||
|
||||
thisEntry["help"] = qHelp
|
||||
self.addLayout(labelBox, self._nextRow, 0, Qt.AlignLeft)
|
||||
self.addLayout(labelBox, self._nextRow, 0, 1, 1, Qt.AlignLeft | Qt.AlignTop)
|
||||
|
||||
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:
|
||||
controlBox = QHBoxLayout()
|
||||
controlBox.addWidget(qWidget, 0, Qt.AlignVCenter)
|
||||
controlBox.addWidget(QLabel(theUnit), 0, Qt.AlignVCenter)
|
||||
controlBox.setSpacing(8)
|
||||
self.addLayout(controlBox, self._nextRow, 1, Qt.AlignRight)
|
||||
self.addLayout(controlBox, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignVCenter)
|
||||
else:
|
||||
self.addWidget(qWidget, self._nextRow, 1, Qt.AlignRight)
|
||||
self.addWidget(qWidget, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignVCenter)
|
||||
|
||||
qLabel.setBuddy(qWidget)
|
||||
|
||||
|
||||
+99
-50
@@ -38,7 +38,8 @@ from PyQt5.QtGui import (
|
||||
)
|
||||
from PyQt5.QtWidgets import (
|
||||
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
|
||||
@@ -119,16 +120,16 @@ class GuiBuildNovel(QDialog):
|
||||
self.fmtSection.setFixedWidth(200)
|
||||
self.fmtSection.setText(self.theProject.titleFormat["section"])
|
||||
|
||||
self.titleForm.addWidget(QLabel("Title"), 0, 0)
|
||||
self.titleForm.addWidget(self.fmtTitle, 0, 1)
|
||||
self.titleForm.addWidget(QLabel("Chapter"), 1, 0)
|
||||
self.titleForm.addWidget(self.fmtChapter, 1, 1)
|
||||
self.titleForm.addWidget(QLabel("Unnumbered"), 2, 0)
|
||||
self.titleForm.addWidget(self.fmtUnnumbered, 2, 1)
|
||||
self.titleForm.addWidget(QLabel("Scene"), 3, 0)
|
||||
self.titleForm.addWidget(self.fmtScene, 3, 1)
|
||||
self.titleForm.addWidget(QLabel("Section"), 4, 0)
|
||||
self.titleForm.addWidget(self.fmtSection, 4, 1)
|
||||
self.titleForm.addWidget(QLabel("Title"), 0, 0, 1, 1, Qt.AlignLeft)
|
||||
self.titleForm.addWidget(self.fmtTitle, 0, 1, 1, 1, Qt.AlignRight)
|
||||
self.titleForm.addWidget(QLabel("Chapter"), 1, 0, 1, 1, Qt.AlignLeft)
|
||||
self.titleForm.addWidget(self.fmtChapter, 1, 1, 1, 1, Qt.AlignRight)
|
||||
self.titleForm.addWidget(QLabel("Unnumbered"), 2, 0, 1, 1, Qt.AlignLeft)
|
||||
self.titleForm.addWidget(self.fmtUnnumbered, 2, 1, 1, 1, Qt.AlignRight)
|
||||
self.titleForm.addWidget(QLabel("Scene"), 3, 0, 1, 1, Qt.AlignLeft)
|
||||
self.titleForm.addWidget(self.fmtScene, 3, 1, 1, 1, Qt.AlignRight)
|
||||
self.titleForm.addWidget(QLabel("Section"), 4, 0, 1, 1, Qt.AlignLeft)
|
||||
self.titleForm.addWidget(self.fmtSection, 4, 1, 1, 1, Qt.AlignRight)
|
||||
|
||||
self.titleForm.setColumnStretch(0, 1)
|
||||
self.titleForm.setColumnStretch(1, 0)
|
||||
@@ -139,11 +140,32 @@ class GuiBuildNovel(QDialog):
|
||||
self.textForm = QGridLayout(self)
|
||||
self.textGroup.setLayout(self.textForm)
|
||||
|
||||
self.justifyText = QSwitch()
|
||||
self.justifyText.setChecked(self.optState.getBool("GuiBuildNovel", "justifyText", False))
|
||||
self.textFont = QFontComboBox()
|
||||
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.textForm.addWidget(self.justifyText, 0, 1)
|
||||
self.textSize = QSpinBox(self)
|
||||
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(1, 0)
|
||||
@@ -156,17 +178,19 @@ class GuiBuildNovel(QDialog):
|
||||
|
||||
self.includeSynopsis = QSwitch()
|
||||
self.includeSynopsis.setChecked(self.theProject.titleFormat["withSynopsis"])
|
||||
|
||||
self.includeComments = QSwitch()
|
||||
self.includeComments.setChecked(self.theProject.titleFormat["withComments"])
|
||||
|
||||
self.includeKeywords = QSwitch()
|
||||
self.includeKeywords.setChecked(self.theProject.titleFormat["withKeywords"])
|
||||
|
||||
self.includeForm.addWidget(QLabel("Include synopsis"), 0, 0)
|
||||
self.includeForm.addWidget(self.includeSynopsis, 0, 1)
|
||||
self.includeForm.addWidget(QLabel("Include comments"), 1, 0)
|
||||
self.includeForm.addWidget(self.includeComments, 1, 1)
|
||||
self.includeForm.addWidget(QLabel("Include keywords"), 2, 0)
|
||||
self.includeForm.addWidget(self.includeKeywords, 2, 1)
|
||||
self.includeForm.addWidget(QLabel("Include synopsis"), 0, 0, 1, 1, Qt.AlignLeft)
|
||||
self.includeForm.addWidget(self.includeSynopsis, 0, 1, 1, 1, Qt.AlignRight)
|
||||
self.includeForm.addWidget(QLabel("Include comments"), 1, 0, 1, 1, Qt.AlignLeft)
|
||||
self.includeForm.addWidget(self.includeComments, 1, 1, 1, 1, Qt.AlignRight)
|
||||
self.includeForm.addWidget(QLabel("Include keywords"), 2, 0, 1, 1, Qt.AlignLeft)
|
||||
self.includeForm.addWidget(self.includeKeywords, 2, 1, 1, 1, Qt.AlignRight)
|
||||
|
||||
self.includeForm.setColumnStretch(0, 1)
|
||||
self.includeForm.setColumnStretch(1, 0)
|
||||
@@ -178,22 +202,33 @@ class GuiBuildNovel(QDialog):
|
||||
self.addsGroup.setLayout(self.addsForm)
|
||||
|
||||
self.novelFiles = QSwitch()
|
||||
self.novelFiles.setChecked(self.optState.getBool("GuiBuildNovel", "addNovel", True))
|
||||
self.noteFiles = QSwitch()
|
||||
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.novelFiles.setChecked(
|
||||
self.optState.getBool("GuiBuildNovel", "addNovel", True)
|
||||
)
|
||||
|
||||
self.addsForm.addWidget(QLabel("Include novel files"), 0, 0)
|
||||
self.addsForm.addWidget(self.novelFiles, 0, 1)
|
||||
self.addsForm.addWidget(QLabel("Include note files"), 1, 0)
|
||||
self.addsForm.addWidget(self.noteFiles, 1, 1)
|
||||
self.addsForm.addWidget(QLabel("Ignore export flag"), 2, 0)
|
||||
self.addsForm.addWidget(self.ignoreFlag, 2, 1)
|
||||
self.addsForm.addWidget(QLabel("Exclude body text"), 3, 0)
|
||||
self.addsForm.addWidget(self.excludeBody, 3, 1)
|
||||
self.noteFiles = QSwitch()
|
||||
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, 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(1, 0)
|
||||
@@ -202,8 +237,8 @@ class GuiBuildNovel(QDialog):
|
||||
# ============
|
||||
self.buildProgress = QProgressBar()
|
||||
|
||||
self.genPreview = QPushButton("Generate Preview")
|
||||
self.genPreview.clicked.connect(self._buildPreview)
|
||||
self.buildNovel = QPushButton("Build Novel Project")
|
||||
self.buildNovel.clicked.connect(self._buildPreview)
|
||||
|
||||
# Action Buttons
|
||||
# ==============
|
||||
@@ -219,28 +254,28 @@ class GuiBuildNovel(QDialog):
|
||||
self.saveMenu = QMenu(self)
|
||||
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.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.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.saveMenu.addAction(self.saveHTM)
|
||||
|
||||
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.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.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.saveMenu.addAction(self.saveTXT)
|
||||
|
||||
@@ -260,7 +295,7 @@ class GuiBuildNovel(QDialog):
|
||||
self.toolsBox.addWidget(self.addsGroup)
|
||||
self.toolsBox.addStretch(1)
|
||||
self.toolsBox.addWidget(self.buildProgress)
|
||||
self.toolsBox.addWidget(self.genPreview)
|
||||
self.toolsBox.addWidget(self.buildNovel)
|
||||
self.toolsBox.addSpacing(8)
|
||||
self.toolsBox.addLayout(self.buttonForm)
|
||||
|
||||
@@ -294,6 +329,8 @@ class GuiBuildNovel(QDialog):
|
||||
fmtScene = self.fmtScene.text().strip()
|
||||
fmtSection = self.fmtSection.text().strip()
|
||||
justifyText = self.justifyText.isChecked()
|
||||
textFont = self.textFont.currentFont().family()
|
||||
textSize = self.textSize.value()
|
||||
incSynopsis = self.includeSynopsis.isChecked()
|
||||
incComments = self.includeComments.isChecked()
|
||||
incKeywords = self.includeKeywords.isChecked()
|
||||
@@ -357,6 +394,7 @@ class GuiBuildNovel(QDialog):
|
||||
self.htmlStyle = makeHtml.getStyleSheet()
|
||||
|
||||
# Load the preview document with the html data
|
||||
self.docView.setTextFont(textFont, textSize)
|
||||
self.docView.setJustify(justifyText)
|
||||
self.docView.setStyleSheet(self.htmlStyle)
|
||||
self.docView.setContent(self.htmlText)
|
||||
@@ -610,12 +648,14 @@ class GuiBuildNovel(QDialog):
|
||||
})
|
||||
|
||||
# GUI Settings
|
||||
self.optState.setValue("GuiBuildNovel", "winWidth", self.width())
|
||||
self.optState.setValue("GuiBuildNovel", "winHeight", self.height())
|
||||
self.optState.setValue("GuiBuildNovel", "winWidth", self.width())
|
||||
self.optState.setValue("GuiBuildNovel", "winHeight", self.height())
|
||||
self.optState.setValue("GuiBuildNovel", "justifyText", self.justifyText.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", "textFont", self.textFont.currentFont().family())
|
||||
self.optState.setValue("GuiBuildNovel", "textSize", self.textSize.value())
|
||||
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.saveSettings()
|
||||
|
||||
@@ -688,6 +728,15 @@ class GuiBuildNovelDocView(QTextBrowser):
|
||||
self.qDocument.setDefaultTextOption(theOpt)
|
||||
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):
|
||||
"""Set the content, either from text or list of text.
|
||||
"""
|
||||
|
||||
@@ -5,7 +5,7 @@ from nw.gui.dialogs.configeditor import GuiConfigEditor
|
||||
from nw.gui.dialogs.docmerge import GuiDocMerge
|
||||
from nw.gui.dialogs.docsplit import GuiDocSplit
|
||||
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.sessionlog import GuiSessionLogView
|
||||
|
||||
@@ -15,7 +15,7 @@ __all__ = [
|
||||
"GuiDocMerge",
|
||||
"GuiDocSplit",
|
||||
"GuiItemEditor",
|
||||
"GuiProjectEditor",
|
||||
"GuiProjectSettings",
|
||||
"GuiProjectLoad",
|
||||
"GuiSessionLogView",
|
||||
]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""novelWriter GUI Project Editor
|
||||
"""novelWriter GUI Project Settings
|
||||
|
||||
novelWriter – GUI Project Editor
|
||||
===================================
|
||||
Class holding the project editor
|
||||
novelWriter – GUI Project Settings
|
||||
====================================
|
||||
Class holding the project settings dialog
|
||||
|
||||
File History:
|
||||
Created: 2018-09-29 [0.0.1]
|
||||
@@ -38,16 +38,16 @@ from PyQt5.QtWidgets import (
|
||||
)
|
||||
|
||||
from nw.constants import nwAlert
|
||||
from nw.gui.additions import QSwitch, PagedDialog
|
||||
from nw.gui.additions import QSwitch, PagedDialog, QConfigLayout
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class GuiProjectEditor(PagedDialog):
|
||||
class GuiProjectSettings(PagedDialog):
|
||||
|
||||
def __init__(self, theParent, theProject):
|
||||
PagedDialog.__init__(self, theParent)
|
||||
|
||||
logger.debug("Initialising ProjectEditor ...")
|
||||
logger.debug("Initialising GuiProjectSettings ...")
|
||||
|
||||
self.mainConf = nw.CONFIG
|
||||
self.theParent = theParent
|
||||
@@ -57,11 +57,13 @@ class GuiProjectEditor(PagedDialog):
|
||||
self.setWindowTitle("Project Settings")
|
||||
|
||||
self.tabMain = GuiProjectEditMain(self.theParent, self.theProject)
|
||||
self.tabStatus = GuiProjectEditStatus(self.theParent, self.theProject.statusItems)
|
||||
self.tabImport = GuiProjectEditStatus(self.theParent, self.theProject.importItems)
|
||||
self.tabMeta = GuiProjectEditMeta(self.theParent, self.theProject)
|
||||
self.tabStatus = GuiProjectEditStatus(self.theParent, self.theProject, True)
|
||||
self.tabImport = GuiProjectEditStatus(self.theParent, self.theProject, False)
|
||||
self.tabReplace = GuiProjectEditReplace(self.theParent, self.theProject)
|
||||
|
||||
self.addTab(self.tabMain, "Settings")
|
||||
self.addTab(self.tabMeta, "Details")
|
||||
self.addTab(self.tabStatus, "Status")
|
||||
self.addTab(self.tabImport, "Importance")
|
||||
self.addTab(self.tabReplace,"Auto-Replace")
|
||||
@@ -73,12 +75,12 @@ class GuiProjectEditor(PagedDialog):
|
||||
|
||||
self.show()
|
||||
|
||||
logger.debug("ProjectEditor initialisation complete")
|
||||
logger.debug("GuiProjectSettings initialisation complete")
|
||||
|
||||
return
|
||||
|
||||
def _doSave(self):
|
||||
logger.verbose("ProjectEditor save button clicked")
|
||||
logger.verbose("GuiProjectSettings save button clicked")
|
||||
|
||||
projName = self.tabMain.editName.text()
|
||||
bookTitle = self.tabMain.editTitle.text()
|
||||
@@ -106,69 +108,166 @@ class GuiProjectEditor(PagedDialog):
|
||||
return
|
||||
|
||||
def _doClose(self):
|
||||
logger.verbose("ProjectEditor close button clicked")
|
||||
logger.verbose("GuiProjectSettings close button clicked")
|
||||
self.close()
|
||||
return
|
||||
|
||||
# END Class GuiProjectEditor
|
||||
# END Class GuiProjectSettings
|
||||
|
||||
class GuiProjectEditMain(QWidget):
|
||||
|
||||
def __init__(self, theParent, theProject):
|
||||
QWidget.__init__(self, theParent)
|
||||
|
||||
self.theParent = theParent
|
||||
self.theProject = theProject
|
||||
self.mainForm = QGridLayout()
|
||||
self.backupBox = QHBoxLayout()
|
||||
self.theParent = theParent
|
||||
self.theProject = theProject
|
||||
|
||||
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.setFixedWidth(250)
|
||||
self.editName.setText(self.theProject.projName)
|
||||
self.mainForm.addRow(
|
||||
"Working title",
|
||||
self.editName,
|
||||
"Should be set only once."
|
||||
)
|
||||
|
||||
self.editTitle = QLineEdit()
|
||||
self.editTitle.setMaxLength(200)
|
||||
self.editTitle.setFixedWidth(250)
|
||||
self.editTitle.setText(self.theProject.bookTitle)
|
||||
self.mainForm.addRow(
|
||||
"Novel title",
|
||||
self.editTitle,
|
||||
"Change whenever you want!"
|
||||
)
|
||||
|
||||
self.editAuthors = QPlainTextEdit()
|
||||
bookAuthors = ""
|
||||
for bookAuthor in self.theProject.bookAuthors:
|
||||
bookAuthors += bookAuthor+"\n"
|
||||
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.setChecked(not self.theProject.doBackup)
|
||||
self.backupBox.addStretch(1)
|
||||
self.backupBox.addWidget(QLabel("Disable backup on close"))
|
||||
self.backupBox.addWidget(self.doBackup)
|
||||
|
||||
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)
|
||||
self.mainForm.addRow(
|
||||
"No backup on close",
|
||||
self.doBackup,
|
||||
"Overrides main preferences."
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
# END Class GuiProjectEditMain
|
||||
|
||||
class GuiProjectEditStatus(QWidget):
|
||||
class GuiProjectEditMeta(QWidget):
|
||||
|
||||
def __init__(self, theParent, theStatus):
|
||||
def __init__(self, theParent, theProject):
|
||||
QWidget.__init__(self, 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.colCounts = []
|
||||
self.colChanged = False
|
||||
self.selColour = None
|
||||
|
||||
self.outerBox = QVBoxLayout()
|
||||
self.mainBox = QHBoxLayout()
|
||||
self.mainForm = QVBoxLayout()
|
||||
|
||||
@@ -208,7 +307,13 @@ class GuiProjectEditStatus(QWidget):
|
||||
self.mainBox.addWidget(self.listBox)
|
||||
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
|
||||
|
||||
@@ -374,6 +479,7 @@ class GuiProjectEditReplace(QWidget):
|
||||
self.bottomBox.addWidget(self.addButton)
|
||||
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.addLayout(self.bottomBox)
|
||||
self.setLayout(self.outerBox)
|
||||
@@ -32,7 +32,9 @@ from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QFont
|
||||
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__)
|
||||
|
||||
@@ -143,27 +145,27 @@ class GuiDocDetails(QFrame):
|
||||
self.pCountData.setAlignment(Qt.AlignRight)
|
||||
|
||||
# Assemble
|
||||
self.mainBox.addWidget(self.labelName, 0, 0, 1, 1, Qt.AlignTop)
|
||||
self.mainBox.addWidget(self.labelFlag, 0, 1, 1, 1, Qt.AlignTop)
|
||||
self.mainBox.addWidget(self.labelData, 0, 2, 1, 3, Qt.AlignTop)
|
||||
self.mainBox.addWidget(self.labelName, 0, 0, 1, 1)
|
||||
self.mainBox.addWidget(self.labelFlag, 0, 1, 1, 1)
|
||||
self.mainBox.addWidget(self.labelData, 0, 2, 1, 3)
|
||||
|
||||
self.mainBox.addWidget(self.statusName, 1, 0, 1, 1, Qt.AlignTop)
|
||||
self.mainBox.addWidget(self.statusFlag, 1, 1, 1, 1, Qt.AlignTop)
|
||||
self.mainBox.addWidget(self.statusData, 1, 2, 1, 1, Qt.AlignTop)
|
||||
self.mainBox.addWidget(self.cCountName, 1, 3, 1, 1, Qt.AlignTop)
|
||||
self.mainBox.addWidget(self.cCountData, 1, 4, 1, 1, Qt.AlignTop)
|
||||
self.mainBox.addWidget(self.statusName, 1, 0, 1, 1)
|
||||
self.mainBox.addWidget(self.statusFlag, 1, 1, 1, 1)
|
||||
self.mainBox.addWidget(self.statusData, 1, 2, 1, 1)
|
||||
self.mainBox.addWidget(self.cCountName, 1, 3, 1, 1)
|
||||
self.mainBox.addWidget(self.cCountData, 1, 4, 1, 1)
|
||||
|
||||
self.mainBox.addWidget(self.className, 2, 0, 1, 1, Qt.AlignTop)
|
||||
self.mainBox.addWidget(self.classFlag, 2, 1, 1, 1, Qt.AlignTop)
|
||||
self.mainBox.addWidget(self.classData, 2, 2, 1, 1, Qt.AlignTop)
|
||||
self.mainBox.addWidget(self.wCountName, 2, 3, 1, 1, Qt.AlignTop)
|
||||
self.mainBox.addWidget(self.wCountData, 2, 4, 1, 1, Qt.AlignTop)
|
||||
self.mainBox.addWidget(self.className, 2, 0, 1, 1)
|
||||
self.mainBox.addWidget(self.classFlag, 2, 1, 1, 1)
|
||||
self.mainBox.addWidget(self.classData, 2, 2, 1, 1)
|
||||
self.mainBox.addWidget(self.wCountName, 2, 3, 1, 1)
|
||||
self.mainBox.addWidget(self.wCountData, 2, 4, 1, 1)
|
||||
|
||||
self.mainBox.addWidget(self.layoutName, 3, 0, 1, 1, Qt.AlignTop)
|
||||
self.mainBox.addWidget(self.layoutFlag, 3, 1, 1, 1, Qt.AlignTop)
|
||||
self.mainBox.addWidget(self.layoutData, 3, 2, 1, 1, Qt.AlignTop)
|
||||
self.mainBox.addWidget(self.pCountName, 3, 3, 1, 1, Qt.AlignTop)
|
||||
self.mainBox.addWidget(self.pCountData, 3, 4, 1, 1, Qt.AlignTop)
|
||||
self.mainBox.addWidget(self.layoutName, 3, 0, 1, 1)
|
||||
self.mainBox.addWidget(self.layoutFlag, 3, 1, 1, 1)
|
||||
self.mainBox.addWidget(self.layoutData, 3, 2, 1, 1)
|
||||
self.mainBox.addWidget(self.pCountName, 3, 3, 1, 1)
|
||||
self.mainBox.addWidget(self.pCountData, 3, 4, 1, 1)
|
||||
|
||||
self.mainBox.setColumnStretch(0,0)
|
||||
self.mainBox.setColumnStretch(1,0)
|
||||
@@ -221,7 +223,10 @@ class GuiDocDetails(QFrame):
|
||||
self.labelFlag.setText(exportFlag)
|
||||
self.statusFlag.setPixmap(flagIcon.pixmap(10, 10))
|
||||
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.statusData.setText(nwItem.itemStatus)
|
||||
|
||||
@@ -85,7 +85,8 @@ class GuiDocEditor(QTextEdit):
|
||||
|
||||
# Document Title
|
||||
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
|
||||
self.hLight = GuiDocHighlighter(self.qDocument, self.theParent)
|
||||
@@ -227,7 +228,6 @@ class GuiDocEditor(QTextEdit):
|
||||
tHandle = self.theHandle
|
||||
self.clearEditor()
|
||||
self.loadText(tHandle, showStatus=False)
|
||||
self.updateDocMargins()
|
||||
return
|
||||
|
||||
def loadText(self, tHandle, tLine=None, showStatus=True):
|
||||
@@ -288,6 +288,7 @@ class GuiDocEditor(QTextEdit):
|
||||
"""
|
||||
self.setPlainText(theText)
|
||||
self.setDocumentChanged(True)
|
||||
self.updateDocMargins()
|
||||
return
|
||||
|
||||
def saveText(self):
|
||||
@@ -336,13 +337,17 @@ class GuiDocEditor(QTextEdit):
|
||||
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()
|
||||
docFormat.setLeftMargin(tM)
|
||||
docFormat.setRightMargin(tM)
|
||||
if docFormat.topMargin() < tH:
|
||||
docFormat.setTopMargin(tH + 2)
|
||||
if tT > 0:
|
||||
docFormat.setTopMargin(tT)
|
||||
else:
|
||||
docFormat.setTopMargin(0)
|
||||
|
||||
# Updating root frame triggers a QTextDocument->contentsChange
|
||||
# signal, which we do not want as it re-runs the syntax
|
||||
@@ -365,6 +370,7 @@ class GuiDocEditor(QTextEdit):
|
||||
"""
|
||||
if tHandle == self.theHandle:
|
||||
self.docTitle.setTitleFromHandle(self.theHandle)
|
||||
self.updateDocMargins()
|
||||
return
|
||||
|
||||
##
|
||||
|
||||
@@ -59,7 +59,8 @@ class GuiDocViewer(QTextBrowser):
|
||||
|
||||
# Document Title
|
||||
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()
|
||||
if self.mainConf.doJustify:
|
||||
@@ -145,6 +146,7 @@ class GuiDocViewer(QTextBrowser):
|
||||
self.theHandle = tHandle
|
||||
self.theProject.setLastViewed(tHandle)
|
||||
self.docTitle.setTitleFromHandle(self.theHandle)
|
||||
self.updateDocMargins()
|
||||
|
||||
# Make sure the main GUI knows we changed the content
|
||||
self.theParent.viewMeta.refreshReferences(tHandle)
|
||||
@@ -206,12 +208,37 @@ class GuiDocViewer(QTextBrowser):
|
||||
self.setSource(QUrl(navLink))
|
||||
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):
|
||||
"""Called when an item label is changed to check if the document
|
||||
title bar needs updating,
|
||||
"""
|
||||
if tHandle == self.theHandle:
|
||||
self.docTitle.setTitleFromHandle(self.theHandle)
|
||||
self.updateDocMargins()
|
||||
return
|
||||
|
||||
##
|
||||
@@ -249,16 +276,7 @@ class GuiDocViewer(QTextBrowser):
|
||||
"""Make sure the document title is the same width as the window.
|
||||
"""
|
||||
QTextBrowser.resizeEvent(self, theEvent)
|
||||
|
||||
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)
|
||||
|
||||
self.updateDocMargins()
|
||||
return
|
||||
|
||||
##
|
||||
|
||||
+2
-2
@@ -42,7 +42,7 @@ from PyQt5.QtWidgets import (
|
||||
from nw.gui import (
|
||||
GuiMainMenu, GuiMainStatus, GuiTheme, GuiDocTree, GuiDocEditor,
|
||||
GuiDocViewer, GuiDocDetails, GuiSearchBar, GuiNoticeBar, GuiDocViewDetails,
|
||||
GuiConfigEditor, GuiProjectEditor, GuiItemEditor, GuiProjectOutline,
|
||||
GuiConfigEditor, GuiProjectSettings, GuiItemEditor, GuiProjectOutline,
|
||||
GuiSessionLogView, GuiDocMerge, GuiDocSplit, GuiProjectLoad, GuiBuildNovel
|
||||
)
|
||||
from nw.core import NWProject, NWDoc, NWIndex
|
||||
@@ -751,7 +751,7 @@ class GuiMain(QMainWindow):
|
||||
"""Open the project settings dialog.
|
||||
"""
|
||||
if self.hasProject:
|
||||
dlgProj = GuiProjectEditor(self, self.theProject)
|
||||
dlgProj = GuiProjectSettings(self, self.theProject)
|
||||
dlgProj.exec_()
|
||||
self._setWindowTitle(self.theProject.projName)
|
||||
return True
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?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>
|
||||
<name></name>
|
||||
<name>New Project</name>
|
||||
<title></title>
|
||||
<backup>True</backup>
|
||||
</project>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?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>
|
||||
<name></name>
|
||||
<name>New Project</name>
|
||||
<title></title>
|
||||
<backup>True</backup>
|
||||
</project>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?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>
|
||||
<name></name>
|
||||
<name>New Project</name>
|
||||
<title></title>
|
||||
<backup>True</backup>
|
||||
</project>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?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>
|
||||
<name></name>
|
||||
<name>New Project</name>
|
||||
<title></title>
|
||||
<backup>True</backup>
|
||||
</project>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?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>
|
||||
<name></name>
|
||||
<name>New Project</name>
|
||||
<title></title>
|
||||
<backup>True</backup>
|
||||
</project>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?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>
|
||||
<name></name>
|
||||
<name>New Project</name>
|
||||
<title></title>
|
||||
<backup>True</backup>
|
||||
</project>
|
||||
|
||||
+6
-5
@@ -8,8 +8,8 @@ from nwtools import *
|
||||
from os import path, unlink
|
||||
from PyQt5.QtCore import Qt
|
||||
|
||||
from nw.gui.dialogs.projecteditor import GuiProjectEditor
|
||||
from nw.gui.dialogs.itemeditor import GuiItemEditor
|
||||
from nw.gui.dialogs.projectsettings import GuiProjectSettings
|
||||
from nw.gui.dialogs.itemeditor import GuiItemEditor
|
||||
|
||||
from nw.constants import *
|
||||
|
||||
@@ -61,7 +61,7 @@ def testMainWindows(qtbot, nwTempGUI, nwRef, nwTemp):
|
||||
assert nwGUI.theProject.projPath == nwTempGUI
|
||||
assert nwGUI.theProject.projMeta == path.join(nwTempGUI,"meta")
|
||||
assert nwGUI.theProject.projFile == "nwProject.nwx"
|
||||
assert nwGUI.theProject.projName == ""
|
||||
assert nwGUI.theProject.projName == "New Project"
|
||||
assert nwGUI.theProject.bookTitle == ""
|
||||
assert len(nwGUI.theProject.bookAuthors) == 0
|
||||
assert nwGUI.theProject.spellCheck == False
|
||||
@@ -262,9 +262,10 @@ def testProjectEditor(qtbot, nwTempGUI, nwRef, nwTemp):
|
||||
assert nwGUI.newProject(nwTempGUI, True)
|
||||
nwGUI.mainConf.backupPath = nwTempGUI
|
||||
|
||||
projEdit = GuiProjectEditor(nwGUI, nwGUI.theProject)
|
||||
projEdit = GuiProjectSettings(nwGUI, nwGUI.theProject)
|
||||
qtbot.addWidget(projEdit)
|
||||
|
||||
projEdit.tabMain.editName.setText("")
|
||||
for c in "Project Name":
|
||||
qtbot.keyClick(projEdit.tabMain.editName, c, delay=keyDelay)
|
||||
for c in "Project Title":
|
||||
@@ -314,7 +315,7 @@ def testProjectEditor(qtbot, nwTempGUI, nwRef, nwTemp):
|
||||
projEdit._doSave()
|
||||
|
||||
# Open again, and check project settings
|
||||
projEdit = GuiProjectEditor(nwGUI, nwGUI.theProject)
|
||||
projEdit = GuiProjectSettings(nwGUI, nwGUI.theProject)
|
||||
qtbot.addWidget(projEdit)
|
||||
assert projEdit.tabMain.editName.text() == "Project Name"
|
||||
assert projEdit.tabMain.editTitle.text() == "Project Title"
|
||||
|
||||
Reference in New Issue
Block a user