From 4ef40f2c4d823aab2b1651b89e96ed7df6e0fd94 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Thu, 25 Jan 2024 21:30:53 +0100 Subject: [PATCH] Remove old project details dialog --- novelwriter/core/options.py | 4 - novelwriter/dialogs/projdetails.py | 518 --------------------- novelwriter/gui/mainmenu.py | 12 +- novelwriter/gui/sidebar.py | 4 +- novelwriter/guimain.py | 13 - tests/test_core/test_core_options.py | 32 +- tests/test_dialogs/test_dlg_projdetails.py | 109 ----- 7 files changed, 22 insertions(+), 670 deletions(-) delete mode 100644 novelwriter/dialogs/projdetails.py delete mode 100644 tests/test_dialogs/test_dlg_projdetails.py 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