Minimal docs update, and add test for Project Details

This commit is contained in:
Veronica K. B. Olsen
2021-01-14 20:09:18 +01:00
parent 84878315d5
commit fb81c7e8e0
4 changed files with 124 additions and 31 deletions
+1
View File
@@ -406,6 +406,7 @@ Most features are available as keyboard shortcuts. These are as follows:
":kbd:`F11`", "Activate full screen mode."
":kbd:`Shift`:kbd:`F1`", "Open the online documentation in the system default browser."
":kbd:`Shift`:kbd:`F3`", "Find previous occurrence of search word in current document. (Same as :kbd:`Ctrl`:kbd:`Shift`:kbd:`G`.)"
":kbd:`Shift`:kbd:`F6`", "Open the :guilabel:`Project Details` dialog."
":kbd:`Return`", "If in the project tree, open a document for editing."
.. note::
+3 -9
View File
@@ -15,7 +15,9 @@ A list of recently opened projects is maintained, and displayed in the :guilabel
dialog. A project can be removed from this list by selecting it and pressing the :kbd:`Del` key.
Project-specific settings are available in :guilabel:`Project Settings` in the :guilabel:`Project`
menu. See further details below in the :ref:`a_proj_settings` section.
menu. See further details below in the :ref:`a_proj_settings` section. Details about the project,
including word counts, and a table of contents with word and page counts, is available through the
:guilabel:`Project Details` dialog.
.. _a_proj_roots:
@@ -249,14 +251,6 @@ override the default spell checking language here. You can also override the aut
setting.
Details Tab
-----------
This tab presents an overview of technical meta data for the project. It states where on your file
system the project is saved, how may times it has been saved, how many folders and documents it
contains, and how many words exist in the entire project.
Status and Importance Tabs
--------------------------
+24 -22
View File
@@ -261,19 +261,19 @@ class GuiProjectDetailsContents(QWidget):
# Contents Tree
# =============
self.chTree = QTreeWidget()
self.chTree.setIconSize(QSize(iPx, iPx))
self.chTree.setIndentation(0)
self.chTree.setColumnCount(6)
self.chTree.setHeaderLabels(["Title", "Words", "Pages", "Page", "Progress", ""])
self.tocTree = QTreeWidget()
self.tocTree.setIconSize(QSize(iPx, iPx))
self.tocTree.setIndentation(0)
self.tocTree.setColumnCount(6)
self.tocTree.setHeaderLabels(["Title", "Words", "Pages", "Page", "Progress", ""])
treeHeadItem = self.chTree.headerItem()
treeHeadItem = self.tocTree.headerItem()
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.chTree.header()
treeHeader = self.tocTree.header()
treeHeader.setStretchLastSection(True)
treeHeader.setMinimumSectionSize(hPx)
@@ -283,12 +283,12 @@ class GuiProjectDetailsContents(QWidget):
wCol3 = self.mainConf.pxInt(self.optState.getInt("GuiProjectDetails", "widthCol3", 60))
wCol4 = self.mainConf.pxInt(self.optState.getInt("GuiProjectDetails", "widthCol4", 90))
self.chTree.setColumnWidth(0, wCol0)
self.chTree.setColumnWidth(1, wCol1)
self.chTree.setColumnWidth(2, wCol2)
self.chTree.setColumnWidth(3, wCol3)
self.chTree.setColumnWidth(4, wCol4)
self.chTree.setColumnWidth(5, hPx)
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
# =======
@@ -334,7 +334,7 @@ class GuiProjectDetailsContents(QWidget):
# ========
self.outerBox = QVBoxLayout()
self.outerBox.addWidget(self.chTree)
self.outerBox.addWidget(self.tocTree)
self.outerBox.addLayout(self.optionsBox)
self.setLayout(self.outerBox)
@@ -348,11 +348,11 @@ class GuiProjectDetailsContents(QWidget):
"""Return the column widths for the tree columns.
"""
retVals = [
self.chTree.columnWidth(0),
self.chTree.columnWidth(1),
self.chTree.columnWidth(2),
self.chTree.columnWidth(3),
self.chTree.columnWidth(4),
self.tocTree.columnWidth(0),
self.tocTree.columnWidth(1),
self.tocTree.columnWidth(2),
self.tocTree.columnWidth(3),
self.tocTree.columnWidth(4),
]
return retVals
@@ -389,19 +389,21 @@ class GuiProjectDetailsContents(QWidget):
pTotal += pCount
theList.append((tLevel, tTitle, wCount, pCount))
self.chTree.clear()
self.tocTree.clear()
for tLevel, tTitle, wCount, pCount in theList:
newItem = QTreeWidgetItem()
if tLevel == "H2":
tTitle = nwUnicode.U_ENSP+tTitle
pgProg = 100.0*(tPages - 1)/pTotal if pTotal > 0 else 0.0
newItem.setIcon(self.C_TITLE, self.theTheme.getIcon("doc_%s" % tLevel.lower()))
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, f"{tPages:n}")
newItem.setText(self.C_PROG, f"{100*(tPages - 1)/pTotal:.1f}{nwUnicode.U_THSP}%")
newItem.setText(self.C_PROG, f"{pgProg:.1f}{nwUnicode.U_THSP}%")
newItem.setTextAlignment(self.C_WORDS, Qt.AlignRight)
newItem.setTextAlignment(self.C_PAGES, Qt.AlignRight)
@@ -410,7 +412,7 @@ class GuiProjectDetailsContents(QWidget):
tPages += pCount
self.chTree.addTopLevelItem(newItem)
self.tocTree.addTopLevelItem(newItem)
return
+96
View File
@@ -0,0 +1,96 @@
# -*- coding: utf-8 -*-
"""novelWriter Writing Stats Dialog Class Tester
"""
import pytest
from tools import getGuiItem
from PyQt5.QtWidgets import QAction, QMessageBox
from nw.gui import GuiProjectDetails
from nw.constants import nwUnicode
keyDelay = 2
typeDelay = 1
stepDelay = 20
@pytest.mark.gui
def testGuiProjDetails_Dialog(qtbot, monkeypatch, nwGUI, nwLipsum):
"""Test the full writing stats tool.
"""
# Block message box
monkeypatch.setattr(QMessageBox, "question", lambda *args: QMessageBox.Yes)
monkeypatch.setattr(QMessageBox, "information", lambda *args: QMessageBox.Yes)
monkeypatch.setattr(QMessageBox, "warning", lambda *args: QMessageBox.Yes)
monkeypatch.setattr(QMessageBox, "critical", lambda *args: QMessageBox.Yes)
# Create a project to work on
assert nwGUI.openProject(nwLipsum)
assert nwGUI.rebuildIndex(beQuiet=True)
qtbot.wait(100)
# Open the Writing Stats dialog
nwGUI.mainConf.lastPath = ""
nwGUI.mainMenu.aProjectDetails.activate(QAction.Trigger)
qtbot.waitUntil(lambda: getGuiItem("GuiProjectDetails") is not None, timeout=1000)
projDet = getGuiItem("GuiProjectDetails")
assert isinstance(projDet, GuiProjectDetails)
qtbot.wait(stepDelay)
# 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"{nwGUI.theProject.saveCount:n}"
assert projDet.tabMain.projPathVal.text() == nwLipsum
# Contents Page
# =============
tocTab = projDet.tabContents
tocTree = tocTab.tocTree
assert tocTree.topLevelItemCount() == 7
assert tocTree.topLevelItem(0).text(tocTab.C_TITLE) == "Lorem Ipsum"
assert tocTree.topLevelItem(2).text(tocTab.C_TITLE) == nwUnicode.U_ENSP+"Prologue"
assert tocTree.topLevelItem(3).text(tocTab.C_TITLE) == "Act One"
assert tocTree.topLevelItem(4).text(tocTab.C_TITLE) == nwUnicode.U_ENSP+"Chapter One"
assert tocTree.topLevelItem(5).text(tocTab.C_TITLE) == nwUnicode.U_ENSP+"Chapter Two"
assert tocTree.topLevelItem(6).text(tocTab.C_TITLE) == "END"
# Count Pages
tocTab.wpValue.setValue(100)
tocTab.dblValue.setChecked(False)
tocTab._populateTree()
thePages = [1, 2, 1, 1, 11, 17, 0]
thePage = [1, 2, 4, 5, 6, 17, 34]
for i in range(7):
assert tocTree.topLevelItem(i).text(tocTab.C_PAGES) == f"{thePages[i]:n}"
assert tocTree.topLevelItem(i).text(tocTab.C_PAGE) == f"{thePage[i]:n}"
tocTab.dblValue.setChecked(True)
tocTab._populateTree()
thePages = [2, 2, 2, 2, 12, 18, 0]
thePage = [1, 3, 5, 7, 9, 21, 39]
for i in range(7):
assert tocTree.topLevelItem(i).text(tocTab.C_PAGES) == f"{thePages[i]:n}"
assert tocTree.topLevelItem(i).text(tocTab.C_PAGE) == f"{thePage[i]:n}"
# qtbot.stopForInteraction()
# Clean Up
projDet._doClose()
nwGUI.closeMain()
monkeypatch.undo()
# END Test testGuiProjDetails_Dialog