diff --git a/novelwriter/core/options.py b/novelwriter/core/options.py
index e2e71296..c48aaa13 100644
--- a/novelwriter/core/options.py
+++ b/novelwriter/core/options.py
@@ -53,10 +53,6 @@ VALID_MAP: dict[str, set[str]] = {
"GuiProjectSettings": {
"winWidth", "winHeight", "replaceColW", "statusColW", "importColW",
},
- "GuiProjectDetails": {
- "winWidth", "winHeight", "widthCol0", "widthCol1", "widthCol2",
- "widthCol3", "widthCol4", "wordsPerPage", "countFrom", "clearDouble",
- },
"GuiWordList": {"winWidth", "winHeight"},
"GuiNovelView": {"lastCol", "lastColSize"},
"GuiBuildSettings": {
diff --git a/novelwriter/dialogs/projdetails.py b/novelwriter/dialogs/projdetails.py
deleted file mode 100644
index 31ffea62..00000000
--- a/novelwriter/dialogs/projdetails.py
+++ /dev/null
@@ -1,518 +0,0 @@
-"""
-novelWriter – GUI Project Details
-=================================
-
-File History:
-Created: 2021-01-03 [1.1rc1] GuiProjectDetails
-
-This file is a part of novelWriter
-Copyright 2018–2024, Veronica Berglyd Olsen
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-"""
-from __future__ import annotations
-
-import math
-import logging
-
-from PyQt5.QtGui import QCloseEvent, QFont
-from PyQt5.QtCore import Qt, QSize, pyqtSlot
-from PyQt5.QtWidgets import (
- QAbstractItemView, QDialogButtonBox, QGridLayout, QHBoxLayout, QLabel,
- QLineEdit, QSpinBox, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
-)
-
-from novelwriter import CONFIG, SHARED
-from novelwriter.common import formatTime, numberToRoman
-from novelwriter.constants import nwUnicode
-from novelwriter.extensions.switch import NSwitch
-from novelwriter.extensions.pageddialog import NPagedDialog
-from novelwriter.extensions.novelselector import NovelSelector
-
-logger = logging.getLogger(__name__)
-
-
-class GuiProjectDetails(NPagedDialog):
-
- def __init__(self, parent: QWidget) -> None:
- super().__init__(parent=parent)
-
- logger.debug("Create: GuiProjectDetails")
- self.setObjectName("GuiProjectDetails")
-
- self.setWindowTitle(self.tr("Project Details"))
-
- wW = CONFIG.pxInt(600)
- wH = CONFIG.pxInt(400)
- pOptions = SHARED.project.options
-
- self.setMinimumWidth(wW)
- self.setMinimumHeight(wH)
- self.resize(
- CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "winWidth", wW)),
- CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "winHeight", wH))
- )
-
- self.tabMain = GuiProjectDetailsMain(self)
- self.tabContents = GuiProjectDetailsContents(self)
-
- self.addTab(self.tabMain, self.tr("Overview"))
- self.addTab(self.tabContents, self.tr("Contents"))
-
- self.buttonBox = QDialogButtonBox(QDialogButtonBox.Close)
- self.buttonBox.rejected.connect(self.close)
- self.rejected.connect(self.close)
- self.addControls(self.buttonBox)
-
- logger.debug("Ready: GuiProjectDetails")
-
- return
-
- def __del__(self) -> None: # pragma: no cover
- logger.debug("Delete: GuiProjectDetails")
- return
-
- def updateValues(self) -> None:
- """Set all the values of the pages."""
- self.tabMain.updateValues()
- self.tabContents.updateValues()
- return
-
- ##
- # Events
- ##
-
- def closeEvent(self, event: QCloseEvent) -> None:
- """Capture the close event and perform cleanup."""
- self._saveGuiSettings()
- event.accept()
- self.deleteLater()
- return
-
- ##
- # Internal Functions
- ##
-
- def _saveGuiSettings(self) -> None:
- """Save GUI settings."""
- winWidth = CONFIG.rpxInt(self.width())
- winHeight = CONFIG.rpxInt(self.height())
-
- cColWidth = self.tabContents.getColumnSizes()
- widthCol0 = CONFIG.rpxInt(cColWidth[0])
- widthCol1 = CONFIG.rpxInt(cColWidth[1])
- widthCol2 = CONFIG.rpxInt(cColWidth[2])
- widthCol3 = CONFIG.rpxInt(cColWidth[3])
- widthCol4 = CONFIG.rpxInt(cColWidth[4])
-
- wordsPerPage = self.tabContents.wpValue.value()
- countFrom = self.tabContents.poValue.value()
- clearDouble = self.tabContents.dblValue.isChecked()
-
- logger.debug("Saving State: GuiProjectDetails")
- pOptions = SHARED.project.options
- pOptions.setValue("GuiProjectDetails", "winWidth", winWidth)
- pOptions.setValue("GuiProjectDetails", "winHeight", winHeight)
- pOptions.setValue("GuiProjectDetails", "widthCol0", widthCol0)
- pOptions.setValue("GuiProjectDetails", "widthCol1", widthCol1)
- pOptions.setValue("GuiProjectDetails", "widthCol2", widthCol2)
- pOptions.setValue("GuiProjectDetails", "widthCol3", widthCol3)
- pOptions.setValue("GuiProjectDetails", "widthCol4", widthCol4)
- pOptions.setValue("GuiProjectDetails", "wordsPerPage", wordsPerPage)
- pOptions.setValue("GuiProjectDetails", "countFrom", countFrom)
- pOptions.setValue("GuiProjectDetails", "clearDouble", clearDouble)
-
- return
-
-# END Class GuiProjectDetails
-
-
-class GuiProjectDetailsMain(QWidget):
-
- def __init__(self, parent: QWidget) -> None:
- super().__init__(parent=parent)
-
- fPx = SHARED.theme.fontPixelSize
- fPt = SHARED.theme.fontPointSize
- vPx = CONFIG.pxInt(4)
- hPx = CONFIG.pxInt(12)
-
- # Header
- # ======
-
- self.bookTitle = QLabel("")
- bookFont = self.bookTitle.font()
- bookFont.setPointSizeF(2.2*fPt)
- bookFont.setWeight(QFont.Bold)
- self.bookTitle.setFont(bookFont)
- self.bookTitle.setAlignment(Qt.AlignHCenter)
- self.bookTitle.setWordWrap(True)
-
- self.projName = QLabel("")
- workFont = self.projName.font()
- workFont.setPointSizeF(0.8*fPt)
- workFont.setItalic(True)
- self.projName.setFont(workFont)
- self.projName.setAlignment(Qt.AlignHCenter)
- self.projName.setWordWrap(True)
-
- self.bookAuthors = QLabel("")
- authFont = self.bookAuthors.font()
- authFont.setPointSizeF(1.2*fPt)
- self.bookAuthors.setFont(authFont)
- self.bookAuthors.setAlignment(Qt.AlignHCenter)
- self.bookAuthors.setWordWrap(True)
-
- # Stats
- # =====
-
- self.wordCountLbl = QLabel("%s:" % self.tr("Words"))
- self.wordCountVal = QLabel("")
-
- self.chapCountLbl = QLabel("%s:" % self.tr("Chapters"))
- self.chapCountVal = QLabel("")
-
- self.sceneCountLbl = QLabel("%s:" % self.tr("Scenes"))
- self.sceneCountVal = QLabel("")
-
- self.revCountLbl = QLabel("%s:" % self.tr("Revisions"))
- self.revCountVal = QLabel("")
-
- self.editTimeLbl = QLabel("%s:" % self.tr("Editing Time"))
- self.editTimeVal = QLabel("")
-
- self.statsGrid = QGridLayout()
- self.statsGrid.addWidget(self.wordCountLbl, 0, 0, 1, 1, Qt.AlignRight)
- self.statsGrid.addWidget(self.wordCountVal, 0, 1, 1, 1, Qt.AlignLeft)
- self.statsGrid.addWidget(self.chapCountLbl, 1, 0, 1, 1, Qt.AlignRight)
- self.statsGrid.addWidget(self.chapCountVal, 1, 1, 1, 1, Qt.AlignLeft)
- self.statsGrid.addWidget(self.sceneCountLbl, 2, 0, 1, 1, Qt.AlignRight)
- self.statsGrid.addWidget(self.sceneCountVal, 2, 1, 1, 1, Qt.AlignLeft)
- self.statsGrid.addWidget(self.revCountLbl, 3, 0, 1, 1, Qt.AlignRight)
- self.statsGrid.addWidget(self.revCountVal, 3, 1, 1, 1, Qt.AlignLeft)
- self.statsGrid.addWidget(self.editTimeLbl, 4, 0, 1, 1, Qt.AlignRight)
- self.statsGrid.addWidget(self.editTimeVal, 4, 1, 1, 1, Qt.AlignLeft)
- self.statsGrid.setHorizontalSpacing(hPx)
- self.statsGrid.setVerticalSpacing(vPx)
-
- # Meta
- # ====
-
- self.projPathLbl = QLabel("%s:" % self.tr("Path"))
- self.projPathVal = QLineEdit()
- self.projPathVal.setReadOnly(True)
-
- self.projPathBox = QHBoxLayout()
- self.projPathBox.addWidget(self.projPathLbl)
- self.projPathBox.addWidget(self.projPathVal)
- self.projPathBox.setSpacing(hPx)
-
- # Assemble
- # ========
-
- self.outerBox = QVBoxLayout()
- self.outerBox.addSpacing(fPx)
- self.outerBox.addWidget(self.bookTitle)
- self.outerBox.addWidget(self.projName)
- self.outerBox.addWidget(self.bookAuthors)
- self.outerBox.addSpacing(2*fPx)
- self.outerBox.addLayout(self.statsGrid)
- self.outerBox.addSpacing(fPx)
- self.outerBox.addStretch(1)
- self.outerBox.addLayout(self.projPathBox)
-
- self.setLayout(self.outerBox)
-
- return
-
- def updateValues(self) -> None:
- """Set all the values."""
- project = SHARED.project
- pIndex = project.index
- hCounts = pIndex.getNovelTitleCounts()
- nwCount = pIndex.getNovelWordCount()
- edTime = project.currentEditTime
-
- self.bookTitle.setText(project.data.title or project.data.name)
- self.projName.setText(self.tr("Project: {0}").format(project.data.name))
- self.bookAuthors.setText(self.tr("By {0}").format(project.data.author))
-
- self.wordCountVal.setText(f"{nwCount:n}")
- self.chapCountVal.setText(f"{hCounts[2]:n}")
- self.sceneCountVal.setText(f"{hCounts[3]:n}")
- self.revCountVal.setText(f"{project.data.saveCount:n}")
- self.editTimeVal.setText(formatTime(edTime))
-
- self.projPathVal.setText(str(project.storage.storagePath))
-
- return
-
-# END Class GuiProjectDetailsMain
-
-
-class GuiProjectDetailsContents(QWidget):
-
- C_TITLE = 0
- C_WORDS = 1
- C_PAGES = 2
- C_PAGE = 3
- C_PROG = 4
-
- def __init__(self, parent: QWidget) -> None:
- super().__init__(parent=parent)
-
- # Internal
- self._theToC = []
- self._currentRoot = None
-
- iPx = SHARED.theme.baseIconSize
- hPx = CONFIG.pxInt(12)
- vPx = CONFIG.pxInt(4)
- pOptions = SHARED.project.options
-
- # Header
- # ======
-
- self.tocLabel = QLabel("%s" % self.tr("Table of Contents"))
-
- self.novelValue = NovelSelector(self)
- self.novelValue.setMinimumWidth(CONFIG.pxInt(200))
- self.novelValue.novelSelectionChanged.connect(self._novelValueChanged)
-
- self.headBox = QHBoxLayout()
- self.headBox.addWidget(self.tocLabel)
- self.headBox.addWidget(self.novelValue)
-
- # Contents Tree
- # =============
-
- self.tocTree = QTreeWidget()
- self.tocTree.setIconSize(QSize(iPx, iPx))
- self.tocTree.setIndentation(0)
- self.tocTree.setColumnCount(6)
- self.tocTree.setSelectionMode(QAbstractItemView.NoSelection)
- self.tocTree.setHeaderLabels([
- self.tr("Title"),
- self.tr("Words"),
- self.tr("Pages"),
- self.tr("Page"),
- self.tr("Progress"),
- ""
- ])
-
- treeHeadItem = self.tocTree.headerItem()
- if treeHeadItem:
- treeHeadItem.setTextAlignment(self.C_WORDS, Qt.AlignRight)
- treeHeadItem.setTextAlignment(self.C_PAGES, Qt.AlignRight)
- treeHeadItem.setTextAlignment(self.C_PAGE, Qt.AlignRight)
- treeHeadItem.setTextAlignment(self.C_PROG, Qt.AlignRight)
-
- treeHeader = self.tocTree.header()
- treeHeader.setStretchLastSection(True)
- treeHeader.setMinimumSectionSize(hPx)
-
- wCol0 = CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol0", 200))
- wCol1 = CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol1", 60))
- wCol2 = CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol2", 60))
- wCol3 = CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol3", 60))
- wCol4 = CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol4", 90))
-
- self.tocTree.setColumnWidth(0, wCol0)
- self.tocTree.setColumnWidth(1, wCol1)
- self.tocTree.setColumnWidth(2, wCol2)
- self.tocTree.setColumnWidth(3, wCol3)
- self.tocTree.setColumnWidth(4, wCol4)
- self.tocTree.setColumnWidth(5, hPx)
-
- # Options
- # =======
-
- wordsPerPage = pOptions.getInt("GuiProjectDetails", "wordsPerPage", 350)
- countFrom = pOptions.getInt("GuiProjectDetails", "countFrom", 1)
- clearDouble = pOptions.getBool("GuiProjectDetails", "clearDouble", True)
-
- wordsHelp = (
- self.tr("Typical word count for a 5 by 8 inch book page with 11 pt font is 350.")
- )
- offsetHelp = (
- self.tr("Start counting page numbers from this page.")
- )
- dblHelp = (
- self.tr("Assume a new chapter or partition always start on an odd numbered page.")
- )
-
- self.wpLabel = QLabel(self.tr("Words per page"))
- self.wpLabel.setToolTip(wordsHelp)
-
- self.wpValue = QSpinBox()
- self.wpValue.setMinimum(10)
- self.wpValue.setMaximum(1000)
- self.wpValue.setSingleStep(10)
- self.wpValue.setValue(wordsPerPage)
- self.wpValue.setToolTip(wordsHelp)
- self.wpValue.valueChanged.connect(self._populateTree)
-
- self.poLabel = QLabel(self.tr("Count pages from"))
- self.poLabel.setToolTip(offsetHelp)
-
- self.poValue = QSpinBox()
- self.poValue.setMinimum(1)
- self.poValue.setMaximum(9999)
- self.poValue.setSingleStep(1)
- self.poValue.setValue(countFrom)
- self.poValue.setToolTip(offsetHelp)
- self.poValue.valueChanged.connect(self._populateTree)
-
- self.dblLabel = QLabel(self.tr("Clear double pages"))
- self.dblLabel.setToolTip(dblHelp)
-
- self.dblValue = NSwitch(self, 2*iPx, iPx)
- self.dblValue.setChecked(clearDouble)
- self.dblValue.setToolTip(dblHelp)
- self.dblValue.clicked.connect(self._populateTree)
-
- self.optionsBox = QGridLayout()
- self.optionsBox.addWidget(self.wpLabel, 0, 0)
- self.optionsBox.addWidget(self.wpValue, 0, 1)
- self.optionsBox.addWidget(self.dblLabel, 0, 3)
- self.optionsBox.addWidget(self.dblValue, 0, 4)
- self.optionsBox.addWidget(self.poLabel, 1, 0)
- self.optionsBox.addWidget(self.poValue, 1, 1)
- self.optionsBox.setHorizontalSpacing(hPx)
- self.optionsBox.setVerticalSpacing(vPx)
- self.optionsBox.setColumnStretch(2, 1)
-
- # Assemble
- # ========
-
- self.outerBox = QVBoxLayout()
- self.outerBox.addLayout(self.headBox)
- self.outerBox.addWidget(self.tocTree)
- self.outerBox.addLayout(self.optionsBox)
-
- self.setLayout(self.outerBox)
-
- return
-
- def getColumnSizes(self) -> list[int]:
- """Return the column widths for the tree columns."""
- retVals = [
- self.tocTree.columnWidth(0),
- self.tocTree.columnWidth(1),
- self.tocTree.columnWidth(2),
- self.tocTree.columnWidth(3),
- self.tocTree.columnWidth(4),
- ]
- return retVals
-
- def updateValues(self) -> None:
- """Populate the tree."""
- self._currentRoot = None
- self.novelValue.refreshNovelList()
- self.novelValue.setHandle(self.novelValue.firstHandle)
- self._prepareData(self.novelValue.firstHandle)
- self._populateTree()
- return
-
- ##
- # Internal Functions
- ##
-
- def _prepareData(self, rootHandle: str | None) -> None:
- """Extract the information from the project index."""
- logger.debug("Populating ToC from handle '%s'", rootHandle)
- self._theToC = SHARED.project.index.getTableOfContents(rootHandle, 2)
- self._theToC.append(("", 0, self.tr("END"), 0))
- return
-
- ##
- # Slots
- ##
-
- @pyqtSlot(str)
- def _novelValueChanged(self, tHandle: str) -> None:
- """Refresh the tree with another root item."""
- if tHandle != self._currentRoot:
- self._prepareData(tHandle)
- self._populateTree()
- self._currentRoot = self.novelValue.handle
- return
-
- @pyqtSlot()
- def _populateTree(self) -> None:
- """Set the content of the chapter/page tree."""
- dblPages = self.dblValue.isChecked()
- wpPage = self.wpValue.value()
- fstPage = self.poValue.value() - 1
-
- pTotal = 0
- tPages = 1
-
- theList = []
- for _, tLevel, tTitle, wCount in self._theToC:
- pCount = math.ceil(wCount/wpPage)
- if dblPages:
- pCount += pCount%2
-
- pTotal += pCount
- theList.append((tLevel, tTitle, wCount, pCount))
-
- pMax = pTotal - fstPage
-
- self.tocTree.clear()
- for tLevel, tTitle, wCount, pCount in theList:
- newItem = QTreeWidgetItem()
-
- if tPages <= fstPage:
- progPage = numberToRoman(tPages, True)
- progText = ""
- else:
- cPage = tPages - fstPage
- pgProg = 100.0*(cPage - 1)/pMax if pMax > 0 else 0.0
- progPage = f"{cPage:n}"
- progText = f"{pgProg:.1f}{nwUnicode.U_THSP}%"
-
- hDec = SHARED.theme.getHeaderDecoration(tLevel)
- if tTitle.strip() == "":
- tTitle = self.tr("Untitled")
-
- newItem.setData(self.C_TITLE, Qt.DecorationRole, hDec)
- newItem.setText(self.C_TITLE, tTitle)
- newItem.setText(self.C_WORDS, f"{wCount:n}")
- newItem.setText(self.C_PAGES, f"{pCount:n}")
- newItem.setText(self.C_PAGE, progPage)
- newItem.setText(self.C_PROG, progText)
-
- newItem.setTextAlignment(self.C_WORDS, Qt.AlignRight)
- newItem.setTextAlignment(self.C_PAGES, Qt.AlignRight)
- newItem.setTextAlignment(self.C_PAGE, Qt.AlignRight)
- newItem.setTextAlignment(self.C_PROG, Qt.AlignRight)
-
- # Make pages and titles/partitions stand out
- if tLevel < 2:
- bFont = newItem.font(self.C_TITLE)
- if tLevel == 0:
- bFont.setItalic(True)
- else:
- bFont.setBold(True)
- bFont.setUnderline(True)
- newItem.setFont(self.C_TITLE, bFont)
-
- tPages += pCount
-
- self.tocTree.addTopLevelItem(newItem)
-
- return
-
-# END Class GuiProjectDetailsContents
diff --git a/novelwriter/gui/mainmenu.py b/novelwriter/gui/mainmenu.py
index 4ad1ab09..279fce07 100644
--- a/novelwriter/gui/mainmenu.py
+++ b/novelwriter/gui/mainmenu.py
@@ -155,14 +155,10 @@ class GuiMainMenu(QMenuBar):
self.aProjectSettings.setShortcut("Ctrl+Shift+,")
self.aProjectSettings.triggered.connect(self.mainGui.showProjectSettingsDialog)
- # Project > Project Details
- self.aProjectDetails = self.projMenu.addAction(self.tr("Project Details"))
- self.aProjectDetails.triggered.connect(self.mainGui.showProjectDetailsDialog)
-
- # Project > Novel Info
- self.aNovelInfo = self.projMenu.addAction(self.tr("Novel Info"))
- self.aNovelInfo.setShortcut("Shift+F6")
- self.aNovelInfo.triggered.connect(self.mainGui.showNovelDetailsDialog)
+ # Project > Novel Details
+ self.aNovelDetails = self.projMenu.addAction(self.tr("Novel Details"))
+ self.aNovelDetails.setShortcut("Shift+F6")
+ self.aNovelDetails.triggered.connect(self.mainGui.showNovelDetailsDialog)
# Project > Separator
self.projMenu.addSeparator()
diff --git a/novelwriter/gui/sidebar.py b/novelwriter/gui/sidebar.py
index 92522542..d425ccf8 100644
--- a/novelwriter/gui/sidebar.py
+++ b/novelwriter/gui/sidebar.py
@@ -79,9 +79,9 @@ class GuiSideBar(QWidget):
self.tbBuild.clicked.connect(self.mainGui.showBuildManuscriptDialog)
self.tbDetails = QToolButton(self)
- self.tbDetails.setToolTip("{0} [Shift+F6]".format(self.tr("Project Details")))
+ self.tbDetails.setToolTip("{0} [Shift+F6]".format(self.tr("Novel Details")))
self.tbDetails.setIconSize(iconSize)
- self.tbDetails.clicked.connect(self.mainGui.showProjectDetailsDialog)
+ self.tbDetails.clicked.connect(self.mainGui.showNovelDetailsDialog)
self.tbStats = QToolButton(self)
self.tbStats.setToolTip("{0} [F6]".format(self.tr("Writing Statistics")))
diff --git a/novelwriter/guimain.py b/novelwriter/guimain.py
index 143d9c65..ad29b741 100644
--- a/novelwriter/guimain.py
+++ b/novelwriter/guimain.py
@@ -53,7 +53,6 @@ from novelwriter.dialogs.about import GuiAbout
from novelwriter.dialogs.updates import GuiUpdates
from novelwriter.dialogs.wordlist import GuiWordList
from novelwriter.dialogs.preferences import GuiPreferences
-from novelwriter.dialogs.projdetails import GuiProjectDetails
from novelwriter.dialogs.projsettings import GuiProjectSettings
from novelwriter.tools.welcome import GuiWelcome
from novelwriter.tools.manuscript import GuiManuscript
@@ -825,18 +824,6 @@ class GuiMain(QMainWindow):
dialog.exec_()
return
- @pyqtSlot()
- def showProjectDetailsDialog(self) -> None:
- """Open the project details dialog."""
- if SHARED.hasProject:
- dialog = GuiProjectDetails(self)
- dialog.setModal(True)
- dialog.show()
- dialog.raise_()
- qApp.processEvents()
- dialog.updateValues()
- return
-
@pyqtSlot()
def showNovelDetailsDialog(self) -> None:
"""Open the novel details dialog."""
diff --git a/tests/test_core/test_core_options.py b/tests/test_core/test_core_options.py
index 7458c746..fd291d08 100644
--- a/tests/test_core/test_core_options.py
+++ b/tests/test_core/test_core_options.py
@@ -121,27 +121,27 @@ def testCoreOptions_SetGet(mockGUI):
assert options.setValue("GuiProjectSettings", "winWidth", 100) is True
# Set some values of different types
- assert options.setValue("GuiProjectDetails", "winWidth", 100) is True
- assert options.setValue("GuiProjectDetails", "winHeight", 12.34) is True
- assert options.setValue("GuiProjectDetails", "clearDouble", True) is True
+ assert options.setValue("GuiNovelDetails", "winWidth", 100) is True
+ assert options.setValue("GuiNovelDetails", "winHeight", 12.34) is True
+ assert options.setValue("GuiNovelDetails", "clearDouble", True) is True
assert options.setValue("GuiNovelView", "lastCol", nwColHidden) is True
# Generic get, doesn't check type
- assert options.getValue("GuiProjectDetails", "winWidth", None) == 100
- assert options.getValue("GuiProjectDetails", "winHeight", None) == 12.34
- assert options.getValue("GuiProjectDetails", "clearDouble", None) is True
- assert options.getValue("GuiProjectDetails", "mockItem", None) is None
+ assert options.getValue("GuiNovelDetails", "winWidth", None) == 100
+ assert options.getValue("GuiNovelDetails", "winHeight", None) == 12.34
+ assert options.getValue("GuiNovelDetails", "clearDouble", None) is True
+ assert options.getValue("GuiNovelDetails", "mockItem", None) is None
# Get type-specific
- assert options.getString("GuiProjectDetails", "winWidth", None) is None # type: ignore
- assert options.getString("GuiProjectDetails", "mockItem", None) is None # type: ignore
- assert options.getInt("GuiProjectDetails", "winWidth", None) == 100 # type: ignore
- assert options.getInt("GuiProjectDetails", "textFont", None) is None # type: ignore
- assert options.getInt("GuiProjectDetails", "mockItem", None) is None # type: ignore
- assert options.getFloat("GuiProjectDetails", "winWidth", None) == 100.0 # type: ignore
- assert options.getFloat("GuiProjectDetails", "mockItem", None) is None # type: ignore
- assert options.getBool("GuiProjectDetails", "clearDouble", None) is True # type: ignore
- assert options.getBool("GuiProjectDetails", "mockItem", None) is None # type: ignore
+ assert options.getString("GuiNovelDetails", "winWidth", None) is None # type: ignore
+ assert options.getString("GuiNovelDetails", "mockItem", None) is None # type: ignore
+ assert options.getInt("GuiNovelDetails", "winWidth", None) == 100 # type: ignore
+ assert options.getInt("GuiNovelDetails", "textFont", None) is None # type: ignore
+ assert options.getInt("GuiNovelDetails", "mockItem", None) is None # type: ignore
+ assert options.getFloat("GuiNovelDetails", "winWidth", None) == 100.0 # type: ignore
+ assert options.getFloat("GuiNovelDetails", "mockItem", None) is None # type: ignore
+ assert options.getBool("GuiNovelDetails", "clearDouble", None) is True # type: ignore
+ assert options.getBool("GuiNovelDetails", "mockItem", None) is None # type: ignore
assert options.getEnum("GuiNovelView", "lastCol", NovelTreeColumn, nwColHidden) == nwColHidden
# Get from non-existent groups
diff --git a/tests/test_dialogs/test_dlg_projdetails.py b/tests/test_dialogs/test_dlg_projdetails.py
deleted file mode 100644
index 3d68f9d7..00000000
--- a/tests/test_dialogs/test_dlg_projdetails.py
+++ /dev/null
@@ -1,109 +0,0 @@
-"""
-novelWriter – Project Details Dialog Class Tester
-=================================================
-
-This file is a part of novelWriter
-Copyright 2018–2024, Veronica Berglyd Olsen
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-"""
-from __future__ import annotations
-
-import pytest
-
-from tools import getGuiItem
-
-from PyQt5.QtWidgets import QAction
-
-from novelwriter import SHARED
-from novelwriter.dialogs.projdetails import GuiProjectDetails
-
-
-@pytest.mark.gui
-def testDlgProjDetails_Dialog(qtbot, nwGUI, prjLipsum):
- """Test the project details dialog.
- """
- # Create a project to work on
- assert nwGUI.openProject(prjLipsum)
- assert nwGUI.rebuildIndex(beQuiet=True)
- qtbot.wait(100)
-
- # Open the Writing Stats dialog
- nwGUI.mainMenu.aProjectDetails.activate(QAction.Trigger)
- qtbot.waitUntil(lambda: getGuiItem("GuiProjectDetails") is not None, timeout=1000)
-
- projDet = getGuiItem("GuiProjectDetails")
- assert isinstance(projDet, GuiProjectDetails)
-
- # Overview Page
- # =============
-
- assert projDet.tabMain.bookTitle.text() == "Lorem Ipsum"
- assert projDet.tabMain.projName.text()[-11:] == "Lorem Ipsum"
- assert projDet.tabMain.bookAuthors.text()[-10:] == "lipsum.com"
-
- assert projDet.tabMain.wordCountVal.text() == f"{3000:n}"
- assert projDet.tabMain.chapCountVal.text() == f"{3:n}"
- assert projDet.tabMain.sceneCountVal.text() == f"{5:n}"
- assert projDet.tabMain.revCountVal.text() == f"{SHARED.project.data.saveCount:n}"
-
- assert projDet.tabMain.projPathVal.text() == str(prjLipsum)
-
- # Contents Page
- # =============
-
- tocTab = projDet.tabContents
- tocTree = tocTab.tocTree
- assert tocTree.topLevelItemCount() == 7
- assert tocTree.topLevelItem(0).text(tocTab.C_TITLE) == "Lorem Ipsum" # type: ignore
- assert tocTree.topLevelItem(2).text(tocTab.C_TITLE) == "Prologue" # type: ignore
- assert tocTree.topLevelItem(3).text(tocTab.C_TITLE) == "Act One" # type: ignore
- assert tocTree.topLevelItem(4).text(tocTab.C_TITLE) == "Chapter One" # type: ignore
- assert tocTree.topLevelItem(5).text(tocTab.C_TITLE) == "Chapter Two" # type: ignore
- assert tocTree.topLevelItem(6).text(tocTab.C_TITLE) == "END" # type: ignore
-
- # Count Pages
- tocTab.wpValue.setValue(100)
- tocTab.poValue.setValue(4)
- tocTab.dblValue.setChecked(False)
- tocTab._populateTree()
-
- thePages = ["1", "2", "1", "1", "11", "17", "0"]
- thePage = ["i", "ii", "1", "2", "3", "14", "31"]
- for i in range(7):
- assert tocTree.topLevelItem(i).text(tocTab.C_PAGES) == thePages[i] # type: ignore
- assert tocTree.topLevelItem(i).text(tocTab.C_PAGE) == thePage[i] # type: ignore
-
- tocTab.poValue.setValue(5)
- tocTab.dblValue.setChecked(True)
- tocTab._populateTree()
-
- thePages = ["2", "2", "2", "2", "12", "18", "0"]
- thePage = ["i", "iii", "1", "3", "5", "17", "35"]
- for i in range(7):
- assert tocTree.topLevelItem(i).text(tocTab.C_PAGES) == thePages[i] # type: ignore
- assert tocTree.topLevelItem(i).text(tocTab.C_PAGE) == thePage[i] # type: ignore
-
- # Re-populate
- assert tocTab._currentRoot is None
- tocTab._novelValueChanged("7a992350f3eb6") # Not a root
- assert tocTab._currentRoot == "b3643d0f92e32" # The actual novel root
-
- # qtbot.stop()
-
- # Clean Up
- projDet.close()
- nwGUI.closeMain()
-
-# END Test testDlgProjDetails_Dialog