GUI and code tweaks and fixes (#852)

* Improve format menu header descriptions
* Ensure that item status is parsed after item class from XML
* Fix column alignment in ToC.txt file
* Rename test variable and fix outdated docstring
* Fix ToC.txt underline
* Rename the Layout label on the item details panel
* Add option to emphasise H1 and H2 labels in the project tree
* Rename the main column of the novel tree to match project tree
* Use the same document icons in the outline as the project tree
* Move project tree settings to Project section of config file
This commit is contained in:
Veronica Berglyd Olsen
2021-08-17 21:45:18 +02:00
committed by GitHub
parent f7c768bb91
commit a9368904e5
16 changed files with 120 additions and 81 deletions
+5 -2
View File
@@ -111,6 +111,7 @@ class Config:
self.hideVScroll = False # Hide vertical scroll bars on main widgets self.hideVScroll = False # Hide vertical scroll bars on main widgets
self.hideHScroll = False # Hide horizontal scroll bars on main widgets self.hideHScroll = False # Hide horizontal scroll bars on main widgets
self.fullStatus = True # Show the full status text in the project tree self.fullStatus = True # Show the full status text in the project tree
self.emphLabels = True # Add emphasis to H1 and H2 item labels
# Project # Project
self.autoSaveProj = 60 # Interval for auto-saving project in seconds self.autoSaveProj = 60 # Interval for auto-saving project in seconds
@@ -451,7 +452,6 @@ class Config:
self.guiLang = theConf.rdStr(cnfSec, "guilang", self.guiLang) self.guiLang = theConf.rdStr(cnfSec, "guilang", self.guiLang)
self.hideVScroll = theConf.rdBool(cnfSec, "hidevscroll", self.hideVScroll) self.hideVScroll = theConf.rdBool(cnfSec, "hidevscroll", self.hideVScroll)
self.hideHScroll = theConf.rdBool(cnfSec, "hidehscroll", self.hideHScroll) self.hideHScroll = theConf.rdBool(cnfSec, "hidehscroll", self.hideHScroll)
self.fullStatus = theConf.rdBool(cnfSec, "fullstatus", self.fullStatus)
# Sizes # Sizes
cnfSec = "Sizes" cnfSec = "Sizes"
@@ -470,6 +470,8 @@ class Config:
cnfSec = "Project" cnfSec = "Project"
self.autoSaveProj = theConf.rdInt(cnfSec, "autosaveproject", self.autoSaveProj) self.autoSaveProj = theConf.rdInt(cnfSec, "autosaveproject", self.autoSaveProj)
self.autoSaveDoc = theConf.rdInt(cnfSec, "autosavedoc", self.autoSaveDoc) self.autoSaveDoc = theConf.rdInt(cnfSec, "autosavedoc", self.autoSaveDoc)
self.fullStatus = theConf.rdBool(cnfSec, "fullstatus", self.fullStatus)
self.emphLabels = theConf.rdBool(cnfSec, "emphlabels", self.emphLabels)
# Editor # Editor
cnfSec = "Editor" cnfSec = "Editor"
@@ -567,7 +569,6 @@ class Config:
"guilang": str(self.guiLang), "guilang": str(self.guiLang),
"hidevscroll": str(self.hideVScroll), "hidevscroll": str(self.hideVScroll),
"hidehscroll": str(self.hideHScroll), "hidehscroll": str(self.hideHScroll),
"fullstatus": str(self.fullStatus),
} }
theConf["Sizes"] = { theConf["Sizes"] = {
@@ -586,6 +587,8 @@ class Config:
theConf["Project"] = { theConf["Project"] = {
"autosaveproject": str(self.autoSaveProj), "autosaveproject": str(self.autoSaveProj),
"autosavedoc": str(self.autoSaveDoc), "autosavedoc": str(self.autoSaveDoc),
"fullstatus": str(self.fullStatus),
"emphlabels": str(self.emphLabels),
} }
theConf["Editor"] = { theConf["Editor"] = {
+5 -1
View File
@@ -107,6 +107,7 @@ class NWItem():
if "order" in xItem.attrib: if "order" in xItem.attrib:
self.setOrder(xItem.attrib["order"]) self.setOrder(xItem.attrib["order"])
tmpStatus = ""
for xValue in xItem: for xValue in xItem:
if xValue.tag == "name": if xValue.tag == "name":
self.setName(xValue.text) self.setName(xValue.text)
@@ -117,7 +118,7 @@ class NWItem():
elif xValue.tag == "layout": elif xValue.tag == "layout":
self.setLayout(xValue.text) self.setLayout(xValue.text)
elif xValue.tag == "status": elif xValue.tag == "status":
self.setStatus(xValue.text) tmpStatus = xValue.text
elif xValue.tag == "expanded": elif xValue.tag == "expanded":
self.setExpanded(xValue.text) self.setExpanded(xValue.text)
elif xValue.tag == "exported": elif xValue.tag == "exported":
@@ -136,6 +137,9 @@ class NWItem():
# version of novelWriter that doesn't know the tag. # version of novelWriter that doesn't know the tag.
logger.error("Unknown tag '%s'", xValue.tag) logger.error("Unknown tag '%s'", xValue.tag)
# Guarantees that <status> is parsed after <class>
self.setStatus(tmpStatus)
return True return True
@staticmethod @staticmethod
+3 -3
View File
@@ -158,7 +158,7 @@ class NWTree():
continue continue
tFile = tHandle+".nwd" tFile = tHandle+".nwd"
if os.path.isfile(os.path.join(self.theProject.projContent, tFile)): if os.path.isfile(os.path.join(self.theProject.projContent, tFile)):
tocLine = "%-25s %-9s %-10s %s" % ( tocLine = "%-25s %-9s %-8s %s" % (
os.path.join("content", tFile), os.path.join("content", tFile),
tItem.itemClass.name, tItem.itemClass.name,
tItem.itemLayout.name, tItem.itemLayout.name,
@@ -175,10 +175,10 @@ class NWTree():
outFile.write("Table of Contents\n") outFile.write("Table of Contents\n")
outFile.write("=================\n") outFile.write("=================\n")
outFile.write("\n") outFile.write("\n")
outFile.write("%-25s %-9s %-10s %s\n" % ( outFile.write("%-25s %-9s %-8s %s\n" % (
"File Name", "Class", "Layout", "Document Label" "File Name", "Class", "Layout", "Document Label"
)) ))
outFile.write("-"*tocLen + "\n") outFile.write("-"*max(tocLen, 62) + "\n")
outFile.write("\n".join(tocList)) outFile.write("\n".join(tocList))
outFile.write("\n") outFile.write("\n")
+21 -4
View File
@@ -94,7 +94,7 @@ class GuiPreferences(PagedDialog):
""" """
logger.debug("Saving new preferences") logger.debug("Saving new preferences")
needsRestart = self.tabGeneral.saveValues() needsRestart, refreshTree = self.tabGeneral.saveValues()
self.tabProjects.saveValues() self.tabProjects.saveValues()
self.tabDocs.saveValues() self.tabDocs.saveValues()
@@ -108,6 +108,9 @@ class GuiPreferences(PagedDialog):
"Some changes will not be applied until novelWriter has been restarted." "Some changes will not be applied until novelWriter has been restarted."
), nwAlert.INFO) ), nwAlert.INFO)
if refreshTree:
self.theParent.treeView.buildTree()
self._saveWindowSize() self._saveWindowSize()
self.accept() self.accept()
@@ -248,7 +251,15 @@ class GuiPreferencesGeneral(QWidget):
self.mainForm.addRow( self.mainForm.addRow(
self.tr("Show status text in project tree"), self.tr("Show status text in project tree"),
self.fullStatus, self.fullStatus,
self.tr("Changing this requires restarting novelWriter."), self.tr("If disabled, only the icon is shown."),
)
self.emphLabels = QSwitch()
self.emphLabels.setChecked(self.mainConf.emphLabels)
self.mainForm.addRow(
self.tr("Emphasise partition and chapter labels"),
self.emphLabels,
self.tr("The novel document labels will be bold and underlined."),
) )
self.showFullPath = QSwitch() self.showFullPath = QSwitch()
@@ -287,6 +298,7 @@ class GuiPreferencesGeneral(QWidget):
guiFont = self.guiFont.text() guiFont = self.guiFont.text()
guiFontSize = self.guiFontSize.value() guiFontSize = self.guiFontSize.value()
fullStatus = self.fullStatus.isChecked() fullStatus = self.fullStatus.isChecked()
emphLabels = self.emphLabels.isChecked()
# Check if restart is needed # Check if restart is needed
needsRestart = False needsRestart = False
@@ -296,7 +308,11 @@ class GuiPreferencesGeneral(QWidget):
needsRestart |= self.mainConf.guiDark != guiDark needsRestart |= self.mainConf.guiDark != guiDark
needsRestart |= self.mainConf.guiFont != guiFont needsRestart |= self.mainConf.guiFont != guiFont
needsRestart |= self.mainConf.guiFontSize != guiFontSize needsRestart |= self.mainConf.guiFontSize != guiFontSize
needsRestart |= self.mainConf.fullStatus != fullStatus
# Check if refreshing project tree is needed
refreshTree = False
refreshTree |= self.mainConf.fullStatus != fullStatus
refreshTree |= self.mainConf.emphLabels != emphLabels
self.mainConf.guiLang = guiLang self.mainConf.guiLang = guiLang
self.mainConf.guiTheme = guiTheme self.mainConf.guiTheme = guiTheme
@@ -305,13 +321,14 @@ class GuiPreferencesGeneral(QWidget):
self.mainConf.guiFont = guiFont self.mainConf.guiFont = guiFont
self.mainConf.guiFontSize = guiFontSize self.mainConf.guiFontSize = guiFontSize
self.mainConf.fullStatus = fullStatus self.mainConf.fullStatus = fullStatus
self.mainConf.emphLabels = emphLabels
self.mainConf.showFullPath = self.showFullPath.isChecked() self.mainConf.showFullPath = self.showFullPath.isChecked()
self.mainConf.hideVScroll = self.hideVScroll.isChecked() self.mainConf.hideVScroll = self.hideVScroll.isChecked()
self.mainConf.hideHScroll = self.hideHScroll.isChecked() self.mainConf.hideHScroll = self.hideHScroll.isChecked()
self.mainConf.confChanged = True self.mainConf.confChanged = True
return needsRestart return needsRestart, refreshTree
## ##
# Slots # Slots
+1 -1
View File
@@ -178,7 +178,7 @@ def exceptionHandler(exType, exValue, exTrace):
errMsg.exec_() errMsg.exec_()
try: try:
# Try a controlled shudown # Try a controlled shutdown
nwGUI.closeProject(isYes=True) nwGUI.closeProject(isYes=True)
nwGUI.closeMain() nwGUI.closeMain()
logger.info("Emergency shutdown successful") logger.info("Emergency shutdown successful")
+33 -33
View File
@@ -72,8 +72,8 @@ class GuiItemDetails(QWidget):
self.labelName.setFont(fntLabel) self.labelName.setFont(fntLabel)
self.labelName.setAlignment(Qt.AlignLeft | Qt.AlignBaseline) self.labelName.setAlignment(Qt.AlignLeft | Qt.AlignBaseline)
self.labelFlag = QLabel("") self.labelIcon = QLabel("")
self.labelFlag.setAlignment(Qt.AlignRight | Qt.AlignBaseline) self.labelIcon.setAlignment(Qt.AlignRight | Qt.AlignBaseline)
self.labelData = QLabel("") self.labelData = QLabel("")
self.labelData.setFont(fntValue) self.labelData.setFont(fntValue)
@@ -85,8 +85,8 @@ class GuiItemDetails(QWidget):
self.statusName.setFont(fntLabel) self.statusName.setFont(fntLabel)
self.statusName.setAlignment(Qt.AlignLeft) self.statusName.setAlignment(Qt.AlignLeft)
self.statusFlag = QLabel("") self.statusIcon = QLabel("")
self.statusFlag.setAlignment(Qt.AlignRight | Qt.AlignVCenter) self.statusIcon.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
self.statusData = QLabel("") self.statusData = QLabel("")
self.statusData.setFont(fntValue) self.statusData.setFont(fntValue)
@@ -97,24 +97,24 @@ class GuiItemDetails(QWidget):
self.className.setFont(fntLabel) self.className.setFont(fntLabel)
self.className.setAlignment(Qt.AlignLeft) self.className.setAlignment(Qt.AlignLeft)
self.classFlag = QLabel("") self.classIcon = QLabel("")
self.classFlag.setAlignment(Qt.AlignRight | Qt.AlignVCenter) self.classIcon.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
self.classData = QLabel("") self.classData = QLabel("")
self.classData.setFont(fntValue) self.classData.setFont(fntValue)
self.classData.setAlignment(Qt.AlignLeft) self.classData.setAlignment(Qt.AlignLeft)
# Layout # Layout
self.layoutName = QLabel(self.tr("Layout")) self.usageName = QLabel(self.tr("Usage"))
self.layoutName.setFont(fntLabel) self.usageName.setFont(fntLabel)
self.layoutName.setAlignment(Qt.AlignLeft) self.usageName.setAlignment(Qt.AlignLeft)
self.layoutFlag = QLabel("") self.usageIcon = QLabel("")
self.layoutFlag.setAlignment(Qt.AlignRight | Qt.AlignVCenter) self.usageIcon.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
self.layoutData = QLabel("") self.usageData = QLabel("")
self.layoutData.setFont(fntValue) self.usageData.setFont(fntValue)
self.layoutData.setAlignment(Qt.AlignLeft) self.usageData.setAlignment(Qt.AlignLeft)
# Character Count # Character Count
self.cCountName = QLabel(" "+self.tr("Characters")) self.cCountName = QLabel(" "+self.tr("Characters"))
@@ -146,24 +146,24 @@ class GuiItemDetails(QWidget):
# Assemble # Assemble
self.mainBox = QGridLayout(self) self.mainBox = QGridLayout(self)
self.mainBox.addWidget(self.labelName, 0, 0, 1, 1) self.mainBox.addWidget(self.labelName, 0, 0, 1, 1)
self.mainBox.addWidget(self.labelFlag, 0, 1, 1, 1) self.mainBox.addWidget(self.labelIcon, 0, 1, 1, 1)
self.mainBox.addWidget(self.labelData, 0, 2, 1, 3) self.mainBox.addWidget(self.labelData, 0, 2, 1, 3)
self.mainBox.addWidget(self.statusName, 1, 0, 1, 1) self.mainBox.addWidget(self.statusName, 1, 0, 1, 1)
self.mainBox.addWidget(self.statusFlag, 1, 1, 1, 1) self.mainBox.addWidget(self.statusIcon, 1, 1, 1, 1)
self.mainBox.addWidget(self.statusData, 1, 2, 1, 1) self.mainBox.addWidget(self.statusData, 1, 2, 1, 1)
self.mainBox.addWidget(self.cCountName, 1, 3, 1, 1) self.mainBox.addWidget(self.cCountName, 1, 3, 1, 1)
self.mainBox.addWidget(self.cCountData, 1, 4, 1, 1) self.mainBox.addWidget(self.cCountData, 1, 4, 1, 1)
self.mainBox.addWidget(self.className, 2, 0, 1, 1) self.mainBox.addWidget(self.className, 2, 0, 1, 1)
self.mainBox.addWidget(self.classFlag, 2, 1, 1, 1) self.mainBox.addWidget(self.classIcon, 2, 1, 1, 1)
self.mainBox.addWidget(self.classData, 2, 2, 1, 1) self.mainBox.addWidget(self.classData, 2, 2, 1, 1)
self.mainBox.addWidget(self.wCountName, 2, 3, 1, 1) self.mainBox.addWidget(self.wCountName, 2, 3, 1, 1)
self.mainBox.addWidget(self.wCountData, 2, 4, 1, 1) self.mainBox.addWidget(self.wCountData, 2, 4, 1, 1)
self.mainBox.addWidget(self.layoutName, 3, 0, 1, 1) self.mainBox.addWidget(self.usageName, 3, 0, 1, 1)
self.mainBox.addWidget(self.layoutFlag, 3, 1, 1, 1) self.mainBox.addWidget(self.usageIcon, 3, 1, 1, 1)
self.mainBox.addWidget(self.layoutData, 3, 2, 1, 1) self.mainBox.addWidget(self.usageData, 3, 2, 1, 1)
self.mainBox.addWidget(self.pCountName, 3, 3, 1, 1) self.mainBox.addWidget(self.pCountName, 3, 3, 1, 1)
self.mainBox.addWidget(self.pCountData, 3, 4, 1, 1) self.mainBox.addWidget(self.pCountData, 3, 4, 1, 1)
@@ -198,15 +198,15 @@ class GuiItemDetails(QWidget):
""" """
self._itemHandle = None self._itemHandle = None
self.labelFlag.setPixmap(QPixmap(1, 1)) self.labelIcon.setPixmap(QPixmap(1, 1))
self.statusFlag.setPixmap(QPixmap(1, 1)) self.statusIcon.setPixmap(QPixmap(1, 1))
self.classFlag.setText("") self.classIcon.setText("")
self.layoutFlag.setText("") self.usageIcon.setText("")
self.labelData.setText("") self.labelData.setText("")
self.statusData.setText("") self.statusData.setText("")
self.classData.setText("") self.classData.setText("")
self.layoutData.setText("") self.usageData.setText("")
self.cCountData.setText("") self.cCountData.setText("")
self.wCountData.setText("") self.wCountData.setText("")
@@ -238,11 +238,11 @@ class GuiItemDetails(QWidget):
if nwItem.itemType == nwItemType.FILE: if nwItem.itemType == nwItemType.FILE:
if nwItem.isExported: if nwItem.isExported:
self.labelFlag.setPixmap(self._expCheck) self.labelIcon.setPixmap(self._expCheck)
else: else:
self.labelFlag.setPixmap(self._expCross) self.labelIcon.setPixmap(self._expCross)
else: else:
self.labelFlag.setPixmap(QPixmap(1, 1)) self.labelIcon.setPixmap(QPixmap(1, 1))
self.labelData.setText(theLabel) self.labelData.setText(theLabel)
@@ -257,25 +257,25 @@ class GuiItemDetails(QWidget):
itStatus = self.theProject.importItems.checkEntry(itStatus) # Make sure it's valid itStatus = self.theProject.importItems.checkEntry(itStatus) # Make sure it's valid
flagIcon = self.theParent.importIcons[itStatus] flagIcon = self.theParent.importIcons[itStatus]
self.statusFlag.setPixmap(flagIcon.pixmap(iPx, iPx)) self.statusIcon.setPixmap(flagIcon.pixmap(iPx, iPx))
self.statusData.setText(nwItem.itemStatus) self.statusData.setText(nwItem.itemStatus)
# Class # Class
# ===== # =====
classIcon = self.theTheme.getIcon(nwLabels.CLASS_ICON[nwItem.itemClass]) classIcon = self.theTheme.getIcon(nwLabels.CLASS_ICON[nwItem.itemClass])
self.classFlag.setPixmap(classIcon.pixmap(iPx, iPx)) self.classIcon.setPixmap(classIcon.pixmap(iPx, iPx))
self.classData.setText(trConst(nwLabels.CLASS_NAME[nwItem.itemClass])) self.classData.setText(trConst(nwLabels.CLASS_NAME[nwItem.itemClass]))
# Layout # Layout
# ====== # ======
hLevel = self.theParent.theIndex.getHandleHeaderLevel(tHandle) hLevel = self.theParent.theIndex.getHandleHeaderLevel(tHandle)
layoutIcon = self.theTheme.getItemIcon( usageIcon = self.theTheme.getItemIcon(
nwItem.itemType, nwItem.itemClass, nwItem.itemLayout, hLevel nwItem.itemType, nwItem.itemClass, nwItem.itemLayout, hLevel
) )
self.layoutFlag.setPixmap(layoutIcon.pixmap(iPx, iPx)) self.usageIcon.setPixmap(usageIcon.pixmap(iPx, iPx))
self.layoutData.setText(nwItem.describeMe(hLevel)) self.usageData.setText(nwItem.describeMe(hLevel))
# Counts # Counts
# ====== # ======
+8 -8
View File
@@ -818,29 +818,29 @@ class GuiMainMenu(QMenuBar):
# Format > Separator # Format > Separator
self.fmtMenu.addSeparator() self.fmtMenu.addSeparator()
# Format > Header 1 # Format > Header 1 (Partition)
self.aFmtHead1 = QAction(self.tr("Header 1"), self) self.aFmtHead1 = QAction(self.tr("Header 1 (Partition)"), self)
self.aFmtHead1.setStatusTip(self.tr("Change the block format to Header 1")) self.aFmtHead1.setStatusTip(self.tr("Change the block format to Header 1"))
self.aFmtHead1.setShortcut("Ctrl+1") self.aFmtHead1.setShortcut("Ctrl+1")
self.aFmtHead1.triggered.connect(lambda: self._docAction(nwDocAction.BLOCK_H1)) self.aFmtHead1.triggered.connect(lambda: self._docAction(nwDocAction.BLOCK_H1))
self.fmtMenu.addAction(self.aFmtHead1) self.fmtMenu.addAction(self.aFmtHead1)
# Format > Header 2 # Format > Header 2 (Chapter)
self.aFmtHead2 = QAction(self.tr("Header 2"), self) self.aFmtHead2 = QAction(self.tr("Header 2 (Chapter)"), self)
self.aFmtHead2.setStatusTip(self.tr("Change the block format to Header 2")) self.aFmtHead2.setStatusTip(self.tr("Change the block format to Header 2"))
self.aFmtHead2.setShortcut("Ctrl+2") self.aFmtHead2.setShortcut("Ctrl+2")
self.aFmtHead2.triggered.connect(lambda: self._docAction(nwDocAction.BLOCK_H2)) self.aFmtHead2.triggered.connect(lambda: self._docAction(nwDocAction.BLOCK_H2))
self.fmtMenu.addAction(self.aFmtHead2) self.fmtMenu.addAction(self.aFmtHead2)
# Format > Header 3 # Format > Header 3 (Scene)
self.aFmtHead3 = QAction(self.tr("Header 3"), self) self.aFmtHead3 = QAction(self.tr("Header 3 (Scene)"), self)
self.aFmtHead3.setStatusTip(self.tr("Change the block format to Header 3")) self.aFmtHead3.setStatusTip(self.tr("Change the block format to Header 3"))
self.aFmtHead3.setShortcut("Ctrl+3") self.aFmtHead3.setShortcut("Ctrl+3")
self.aFmtHead3.triggered.connect(lambda: self._docAction(nwDocAction.BLOCK_H3)) self.aFmtHead3.triggered.connect(lambda: self._docAction(nwDocAction.BLOCK_H3))
self.fmtMenu.addAction(self.aFmtHead3) self.fmtMenu.addAction(self.aFmtHead3)
# Format > Header 4 # Format > Header 4 (Section)
self.aFmtHead4 = QAction(self.tr("Header 4"), self) self.aFmtHead4 = QAction(self.tr("Header 4 (Section)"), self)
self.aFmtHead4.setStatusTip(self.tr("Change the block format to Header 4")) self.aFmtHead4.setStatusTip(self.tr("Change the block format to Header 4"))
self.aFmtHead4.setShortcut("Ctrl+4") self.aFmtHead4.setShortcut("Ctrl+4")
self.aFmtHead4.triggered.connect(lambda: self._docAction(nwDocAction.BLOCK_H4)) self.aFmtHead4.triggered.connect(lambda: self._docAction(nwDocAction.BLOCK_H4))
+1 -1
View File
@@ -64,7 +64,7 @@ class GuiNovelTree(QTreeWidget):
self.setIndentation(iPx) self.setIndentation(iPx)
self.setColumnCount(3) self.setColumnCount(3)
self.setHeaderLabels([ self.setHeaderLabels([
self.tr("Title"), self.tr("Novel Outline"),
self.tr("Words"), self.tr("Words"),
self.tr("POV") self.tr("POV")
]) ])
+5 -2
View File
@@ -33,7 +33,7 @@ from PyQt5.QtWidgets import (
QTreeWidget, QTreeWidgetItem, QMenu, QAction, QAbstractItemView QTreeWidget, QTreeWidgetItem, QMenu, QAction, QAbstractItemView
) )
from nw.enum import nwOutline from nw.enum import nwItemLayout, nwItemType, nwOutline
from nw.constants import trConst, nwKeyWords, nwLabels from nw.constants import trConst, nwKeyWords, nwLabels
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -434,6 +434,9 @@ class GuiOutline(QTreeWidget):
newItem = QTreeWidgetItem() newItem = QTreeWidgetItem()
hIcon = "doc_%s" % novIdx["level"].lower() hIcon = "doc_%s" % novIdx["level"].lower()
hLevel = self.theIndex.getHandleHeaderLevel(tHandle)
dIcon = self.theTheme.getItemIcon(nwItemType.FILE, None, nwItemLayout.DOCUMENT, hLevel)
cC = int(novIdx["cCount"]) cC = int(novIdx["cCount"])
wC = int(novIdx["wCount"]) wC = int(novIdx["wCount"])
pC = int(novIdx["pCount"]) pC = int(novIdx["pCount"])
@@ -443,7 +446,7 @@ class GuiOutline(QTreeWidget):
newItem.setIcon(self._colIdx[nwOutline.TITLE], self.theTheme.getIcon(hIcon)) newItem.setIcon(self._colIdx[nwOutline.TITLE], self.theTheme.getIcon(hIcon))
newItem.setText(self._colIdx[nwOutline.LEVEL], novIdx["level"]) newItem.setText(self._colIdx[nwOutline.LEVEL], novIdx["level"])
newItem.setText(self._colIdx[nwOutline.LABEL], nwItem.itemName) newItem.setText(self._colIdx[nwOutline.LABEL], nwItem.itemName)
newItem.setIcon(self._colIdx[nwOutline.LABEL], self.theTheme.getIcon("proj_document")) newItem.setIcon(self._colIdx[nwOutline.LABEL], dIcon)
newItem.setText(self._colIdx[nwOutline.LINE], sTitle[1:].lstrip("0")) newItem.setText(self._colIdx[nwOutline.LINE], sTitle[1:].lstrip("0"))
newItem.setData(self._colIdx[nwOutline.LINE], Qt.UserRole, sTitle) newItem.setData(self._colIdx[nwOutline.LINE], Qt.UserRole, sTitle)
newItem.setText(self._colIdx[nwOutline.SYNOP], novIdx["synopsis"]) newItem.setText(self._colIdx[nwOutline.SYNOP], novIdx["synopsis"])
+13 -1
View File
@@ -86,7 +86,7 @@ class GuiProjectTree(QTreeWidget):
self.setIndentation(iPx) self.setIndentation(iPx)
self.setColumnCount(4) self.setColumnCount(4)
self.setHeaderLabels([ self.setHeaderLabels([
self.tr("Label"), self.tr("Words"), "", self.tr("Project Tree"), self.tr("Words"), "",
self.tr("Status") if self.mainConf.fullStatus else "" self.tr("Status") if self.mainConf.fullStatus else ""
]) ])
@@ -636,6 +636,13 @@ class GuiProjectTree(QTreeWidget):
else: else:
trItem.setToolTip(self.C_STATUS, nwItem.itemStatus) trItem.setToolTip(self.C_STATUS, nwItem.itemStatus)
if self.mainConf.emphLabels and nwItem.itemLayout == nwItemLayout.DOCUMENT:
if hLevel in ("H1", "H2"):
trFont = trItem.font(self.C_NAME)
trFont.setBold(True)
trFont.setUnderline(True)
trItem.setFont(self.C_NAME, trFont)
return return
def propagateCount(self, tHandle, theCount, nDepth=0): def propagateCount(self, tHandle, theCount, nDepth=0):
@@ -695,6 +702,11 @@ class GuiProjectTree(QTreeWidget):
logger.debug("Building the project tree ...") logger.debug("Building the project tree ...")
self.clearTree() self.clearTree()
self.setHeaderLabels([
self.tr("Project Tree"), self.tr("Words"), "",
self.tr("Status") if self.mainConf.fullStatus else ""
])
iCount = 0 iCount = 0
for nwItem in self.theProject.getProjectItems(): for nwItem in self.theProject.getProjectItems():
iCount += 1 iCount += 1
+1 -3
View File
@@ -502,9 +502,7 @@ class GuiWritingStats(QDialog):
## ##
def _updateListBox(self): def _updateListBox(self):
"""Load/reload the content of the list box. The dummyVar """Load/reload the content of the list box.
variable captures the variable sent from the widgets connecting
to it and discards it.
""" """
self.listBox.clear() self.listBox.clear()
self.timeFilter = 0.0 self.timeFilter = 0.0
+3 -2
View File
@@ -1,5 +1,5 @@
[Main] [Main]
timestamp = 2021-02-15 16:31:24 timestamp = 2021-08-17 20:59:39
theme = default theme = default
syntax = default_light syntax = default_light
icons = typicons_colour_light icons = typicons_colour_light
@@ -10,7 +10,6 @@ lastnotes = 0x0
guilang = en_GB guilang = en_GB
hidevscroll = False hidevscroll = False
hidehscroll = False hidehscroll = False
fullstatus = True
[Sizes] [Sizes]
geometry = 1200, 650 geometry = 1200, 650
@@ -27,6 +26,8 @@ fullscreen = False
[Project] [Project]
autosaveproject = 60 autosaveproject = 60
autosavedoc = 30 autosavedoc = 30
fullstatus = True
emphlabels = True
[Editor] [Editor]
textfont = None textfont = None
@@ -1,5 +1,5 @@
[Main] [Main]
timestamp = 2021-02-09 21:07:17 timestamp = 2021-08-17 20:59:42
theme = default theme = default
syntax = default_light syntax = default_light
icons = typicons_colour_light icons = typicons_colour_light
@@ -10,7 +10,6 @@ lastnotes = 0x0
guilang = en_GB guilang = en_GB
hidevscroll = True hidevscroll = True
hidehscroll = True hidehscroll = True
fullstatus = True
[Sizes] [Sizes]
geometry = 1200, 650 geometry = 1200, 650
@@ -27,6 +26,8 @@ fullscreen = False
[Project] [Project]
autosaveproject = 40 autosaveproject = 40
autosavedoc = 20 autosavedoc = 20
fullstatus = True
emphlabels = True
[Editor] [Editor]
textfont = None textfont = None
+10 -10
View File
@@ -47,10 +47,10 @@ def testCoreOptions_LoadSave(monkeypatch, mockGUI, tmpDir):
"addNovel": True, "addNovel": True,
"addNotes": False, "addNotes": False,
"textFont": "Cantarell", "textFont": "Cantarell",
"dummyItem": None, "mockItem": None,
}, },
"DummyGroup": { "MockGroup": {
"dummyItem": None, "mockItem": None,
}, },
})) }))
@@ -109,8 +109,8 @@ def testCoreOptions_SetGet(mockGUI):
theOpts = OptionState(theProject) theOpts = OptionState(theProject)
# Set invalid values # Set invalid values
assert not theOpts.setValue("DummyGroup", "dummyItem", None) assert not theOpts.setValue("MockGroup", "mockItem", None)
assert not theOpts.setValue("GuiBuildNovel", "dummyItem", None) assert not theOpts.setValue("GuiBuildNovel", "mockItem", None)
# Set valid value # Set valid value
assert theOpts.setValue("GuiBuildNovel", "winWidth", 100) assert theOpts.setValue("GuiBuildNovel", "winWidth", 100)
@@ -126,19 +126,19 @@ def testCoreOptions_SetGet(mockGUI):
assert theOpts.getValue("GuiBuildNovel", "winHeight", None) == 12.34 assert theOpts.getValue("GuiBuildNovel", "winHeight", None) == 12.34
assert theOpts.getValue("GuiBuildNovel", "addNovel", None) is True assert theOpts.getValue("GuiBuildNovel", "addNovel", None) is True
assert theOpts.getValue("GuiBuildNovel", "textFont", None) == "Cantarell" assert theOpts.getValue("GuiBuildNovel", "textFont", None) == "Cantarell"
assert theOpts.getValue("GuiBuildNovel", "dummyItem", None) is None assert theOpts.getValue("GuiBuildNovel", "mockItem", None) is None
# Get type-specific # Get type-specific
assert theOpts.getString("GuiBuildNovel", "winWidth", None) == "100" assert theOpts.getString("GuiBuildNovel", "winWidth", None) == "100"
assert theOpts.getString("GuiBuildNovel", "dummyItem", None) is None assert theOpts.getString("GuiBuildNovel", "mockItem", None) is None
assert theOpts.getInt("GuiBuildNovel", "winWidth", None) == 100 assert theOpts.getInt("GuiBuildNovel", "winWidth", None) == 100
assert theOpts.getInt("GuiBuildNovel", "textFont", None) is None assert theOpts.getInt("GuiBuildNovel", "textFont", None) is None
assert theOpts.getInt("GuiBuildNovel", "dummyItem", None) is None assert theOpts.getInt("GuiBuildNovel", "mockItem", None) is None
assert theOpts.getFloat("GuiBuildNovel", "winWidth", None) == 100.0 assert theOpts.getFloat("GuiBuildNovel", "winWidth", None) == 100.0
assert theOpts.getFloat("GuiBuildNovel", "textFont", None) is None assert theOpts.getFloat("GuiBuildNovel", "textFont", None) is None
assert theOpts.getFloat("GuiBuildNovel", "dummyItem", None) is None assert theOpts.getFloat("GuiBuildNovel", "mockItem", None) is None
assert theOpts.getBool("GuiBuildNovel", "addNovel", None) is True assert theOpts.getBool("GuiBuildNovel", "addNovel", None) is True
assert theOpts.getBool("GuiBuildNovel", "dummyItem", None) is None assert theOpts.getBool("GuiBuildNovel", "mockItem", None) is None
# Check integer validators # Check integer validators
assert theOpts.validIntRange(5, 0, 9, 3) == 5 assert theOpts.validIntRange(5, 0, 9, 3) == 5
+7 -7
View File
@@ -434,7 +434,7 @@ def testCoreTree_ToCFile(monkeypatch, mockGUI, mockItems, tmpDir):
assert len(theTree) == len(mockItems) assert len(theTree) == len(mockItems)
theTree._treeOrder.append("stuff") theTree._treeOrder.append("stuff")
def dummyIsFile(fileName): def mockIsFile(fileName):
"""Return True for items that are files in novelWriter and """Return True for items that are files in novelWriter and
should thus also be files in the project folder structure. should thus also be files in the project folder structure.
""" """
@@ -442,7 +442,7 @@ def testCoreTree_ToCFile(monkeypatch, mockGUI, mockItems, tmpDir):
assert dItem is not None assert dItem is not None
return dItem.itemType == nwItemType.FILE return dItem.itemType == nwItemType.FILE
monkeypatch.setattr("os.path.isfile", dummyIsFile) monkeypatch.setattr("os.path.isfile", mockIsFile)
theProject.projContent = "content" theProject.projContent = "content"
theProject.projPath = None theProject.projPath = None
@@ -460,11 +460,11 @@ def testCoreTree_ToCFile(monkeypatch, mockGUI, mockItems, tmpDir):
"Table of Contents\n" "Table of Contents\n"
"=================\n" "=================\n"
"\n" "\n"
"File Name Class Layout Document Label\n" "File Name Class Layout Document Label\n"
"-------------------------------------------------------------\n" "--------------------------------------------------------------\n"
f"{pathA} NOVEL DOCUMENT Chapter One\n" f"{pathA} NOVEL DOCUMENT Chapter One\n"
f"{pathB} NOVEL DOCUMENT Scene One\n" f"{pathB} NOVEL DOCUMENT Scene One\n"
f"{pathC} CHARACTER NOTE Jane Doe\n" f"{pathC} CHARACTER NOTE Jane Doe\n"
) )
# END Test testCoreTree_ToCFile # END Test testCoreTree_ToCFile
+1 -1
View File
@@ -249,7 +249,7 @@ def testDlgPreferences_Main(qtbot, monkeypatch, fncDir, outDir, refDir):
testFile = os.path.join(outDir, "guiPreferences_novelwriter.conf") testFile = os.path.join(outDir, "guiPreferences_novelwriter.conf")
compFile = os.path.join(refDir, "guiPreferences_novelwriter.conf") compFile = os.path.join(refDir, "guiPreferences_novelwriter.conf")
copyfile(projFile, testFile) copyfile(projFile, testFile)
ignoreLines = [2, 7, 9, 10, 16, 17, 18, 19, 20, 21, 22, 23, 24, 32, 33] ignoreLines = [2, 7, 9, 10, 15, 16, 17, 18, 19, 20, 21, 22, 23, 33, 34]
assert cmpFiles(testFile, compFile, ignoreLines) assert cmpFiles(testFile, compFile, ignoreLines)
# Clean up # Clean up