Merge branch 'main' into primary_count

This commit is contained in:
Veronica Berglyd Olsen
2025-05-12 19:41:33 +02:00
42 changed files with 490 additions and 278 deletions
+2 -1
View File
@@ -1,5 +1,5 @@
[Meta]
timestamp = 2025-02-22 19:57:47
timestamp = 2025-05-11 13:28:11
[Main]
font =
@@ -31,6 +31,7 @@ backuppath =
backuponclose = False
askbeforebackup = True
askbeforeexit = True
lastauthor =
[Editor]
textfont =
@@ -16,16 +16,16 @@
</lastHandle>
<autoReplace />
<status>
<entry key="s000000" count="7" red="100" green="100" blue="100" shape="SQUARE">New</entry>
<entry key="s000001" count="0" red="200" green="50" blue="0" shape="SQUARE">Note</entry>
<entry key="s000002" count="0" red="200" green="150" blue="0" shape="SQUARE">Draft</entry>
<entry key="s000003" count="0" red="50" green="200" blue="0" shape="SQUARE">Finished</entry>
<entry key="s000000" count="7" red="120" green="120" blue="120" shape="STAR">New</entry>
<entry key="s000001" count="0" red="205" green="171" blue="143" shape="TRIANGLE">Note</entry>
<entry key="s000002" count="0" red="143" green="240" blue="164" shape="CIRCLE_T">Draft</entry>
<entry key="s000003" count="0" red="249" green="240" blue="107" shape="STAR">Finished</entry>
</status>
<importance>
<entry key="i000004" count="5" red="100" green="100" blue="100" shape="SQUARE">New</entry>
<entry key="i000005" count="0" red="200" green="50" blue="0" shape="SQUARE">Minor</entry>
<entry key="i000006" count="0" red="200" green="150" blue="0" shape="SQUARE">Major</entry>
<entry key="i000007" count="0" red="50" green="200" blue="0" shape="SQUARE">Main</entry>
<entry key="i000004" count="5" red="120" green="120" blue="120" shape="SQUARE">New</entry>
<entry key="i000005" count="0" red="220" green="138" blue="221" shape="BLOCK_2">Minor</entry>
<entry key="i000006" count="0" red="220" green="138" blue="221" shape="BLOCK_3">Major</entry>
<entry key="i000007" count="0" red="220" green="138" blue="221" shape="BLOCK_4">Main</entry>
</importance>
</settings>
<content items="12" novelWords="10" notesWords="6" novelChars="45" notesChars="22">
@@ -16,16 +16,16 @@
</lastHandle>
<autoReplace />
<status>
<entry key="s000000" count="6" red="100" green="100" blue="100" shape="SQUARE">New</entry>
<entry key="s000001" count="0" red="200" green="50" blue="0" shape="SQUARE">Note</entry>
<entry key="s000002" count="0" red="200" green="150" blue="0" shape="SQUARE">Draft</entry>
<entry key="s000003" count="0" red="50" green="200" blue="0" shape="SQUARE">Finished</entry>
<entry key="s000000" count="6" red="120" green="120" blue="120" shape="STAR">New</entry>
<entry key="s000001" count="0" red="205" green="171" blue="143" shape="TRIANGLE">Note</entry>
<entry key="s000002" count="0" red="143" green="240" blue="164" shape="CIRCLE_T">Draft</entry>
<entry key="s000003" count="0" red="249" green="240" blue="107" shape="STAR">Finished</entry>
</status>
<importance>
<entry key="i000004" count="10" red="100" green="100" blue="100" shape="SQUARE">New</entry>
<entry key="i000005" count="0" red="200" green="50" blue="0" shape="SQUARE">Minor</entry>
<entry key="i000006" count="0" red="200" green="150" blue="0" shape="SQUARE">Major</entry>
<entry key="i000007" count="0" red="50" green="200" blue="0" shape="SQUARE">Main</entry>
<entry key="i000004" count="10" red="120" green="120" blue="120" shape="SQUARE">New</entry>
<entry key="i000005" count="0" red="220" green="138" blue="221" shape="BLOCK_2">Minor</entry>
<entry key="i000006" count="0" red="220" green="138" blue="221" shape="BLOCK_3">Major</entry>
<entry key="i000007" count="0" red="220" green="138" blue="221" shape="BLOCK_4">Main</entry>
</importance>
</settings>
<content items="16" novelWords="9" notesWords="0" novelChars="40" notesChars="0">
@@ -16,16 +16,16 @@
</lastHandle>
<autoReplace />
<status>
<entry key="s000000" count="16" red="100" green="100" blue="100" shape="SQUARE">New</entry>
<entry key="s000001" count="0" red="200" green="50" blue="0" shape="SQUARE">Note</entry>
<entry key="s000002" count="0" red="200" green="150" blue="0" shape="SQUARE">Draft</entry>
<entry key="s000003" count="0" red="50" green="200" blue="0" shape="SQUARE">Finished</entry>
<entry key="s000000" count="16" red="120" green="120" blue="120" shape="STAR">New</entry>
<entry key="s000001" count="0" red="205" green="171" blue="143" shape="TRIANGLE">Note</entry>
<entry key="s000002" count="0" red="143" green="240" blue="164" shape="CIRCLE_T">Draft</entry>
<entry key="s000003" count="0" red="249" green="240" blue="107" shape="STAR">Finished</entry>
</status>
<importance>
<entry key="i000004" count="3" red="100" green="100" blue="100" shape="SQUARE">New</entry>
<entry key="i000005" count="0" red="200" green="50" blue="0" shape="SQUARE">Minor</entry>
<entry key="i000006" count="0" red="200" green="150" blue="0" shape="SQUARE">Major</entry>
<entry key="i000007" count="0" red="50" green="200" blue="0" shape="SQUARE">Main</entry>
<entry key="i000004" count="3" red="120" green="120" blue="120" shape="SQUARE">New</entry>
<entry key="i000005" count="0" red="220" green="138" blue="221" shape="BLOCK_2">Minor</entry>
<entry key="i000006" count="0" red="220" green="138" blue="221" shape="BLOCK_3">Major</entry>
<entry key="i000007" count="0" red="220" green="138" blue="221" shape="BLOCK_4">Main</entry>
</importance>
</settings>
<content items="19" novelWords="28" notesWords="0" novelChars="129" notesChars="0">
@@ -1,6 +1,6 @@
Jane Doe
Address 1
Address 2
Address Line 1
Address Line 2
@@ -17,7 +17,7 @@ Test Project A
**By Jane Doe**
Word Count: 11
Word Count: 13
# Chapter 1
@@ -16,16 +16,16 @@
</lastHandle>
<autoReplace />
<status>
<entry key="s000000" count="15" red="100" green="100" blue="100" shape="SQUARE">New</entry>
<entry key="s000001" count="0" red="200" green="50" blue="0" shape="SQUARE">Note</entry>
<entry key="s000002" count="0" red="200" green="150" blue="0" shape="SQUARE">Draft</entry>
<entry key="s000003" count="0" red="50" green="200" blue="0" shape="SQUARE">Finished</entry>
<entry key="s000000" count="15" red="120" green="120" blue="120" shape="STAR">New</entry>
<entry key="s000001" count="0" red="205" green="171" blue="143" shape="TRIANGLE">Note</entry>
<entry key="s000002" count="0" red="143" green="240" blue="164" shape="CIRCLE_T">Draft</entry>
<entry key="s000003" count="0" red="249" green="240" blue="107" shape="STAR">Finished</entry>
</status>
<importance>
<entry key="i000004" count="7" red="100" green="100" blue="100" shape="SQUARE">New</entry>
<entry key="i000005" count="0" red="200" green="50" blue="0" shape="SQUARE">Minor</entry>
<entry key="i000006" count="0" red="200" green="150" blue="0" shape="SQUARE">Major</entry>
<entry key="i000007" count="0" red="50" green="200" blue="0" shape="SQUARE">Main</entry>
<entry key="i000004" count="7" red="120" green="120" blue="120" shape="SQUARE">New</entry>
<entry key="i000005" count="0" red="220" green="138" blue="221" shape="BLOCK_2">Minor</entry>
<entry key="i000006" count="0" red="220" green="138" blue="221" shape="BLOCK_3">Major</entry>
<entry key="i000007" count="0" red="220" green="138" blue="221" shape="BLOCK_4">Main</entry>
</importance>
</settings>
<content items="22" novelWords="0" notesWords="0" novelChars="0" notesChars="0">
@@ -1,6 +1,6 @@
Jane Doe
Address 1
Address 2
Address Line 1
Address Line 2
@@ -17,7 +17,7 @@ Test Project B
**By Jane Doe**
Word Count: 11
Word Count: 13
* * *
@@ -16,16 +16,16 @@
</lastHandle>
<autoReplace />
<status>
<entry key="s000000" count="9" red="100" green="100" blue="100" shape="SQUARE">New</entry>
<entry key="s000001" count="0" red="200" green="50" blue="0" shape="SQUARE">Note</entry>
<entry key="s000002" count="0" red="200" green="150" blue="0" shape="SQUARE">Draft</entry>
<entry key="s000003" count="0" red="50" green="200" blue="0" shape="SQUARE">Finished</entry>
<entry key="s000000" count="9" red="120" green="120" blue="120" shape="STAR">New</entry>
<entry key="s000001" count="0" red="205" green="171" blue="143" shape="TRIANGLE">Note</entry>
<entry key="s000002" count="0" red="143" green="240" blue="164" shape="CIRCLE_T">Draft</entry>
<entry key="s000003" count="0" red="249" green="240" blue="107" shape="STAR">Finished</entry>
</status>
<importance>
<entry key="i000004" count="7" red="100" green="100" blue="100" shape="SQUARE">New</entry>
<entry key="i000005" count="0" red="200" green="50" blue="0" shape="SQUARE">Minor</entry>
<entry key="i000006" count="0" red="200" green="150" blue="0" shape="SQUARE">Major</entry>
<entry key="i000007" count="0" red="50" green="200" blue="0" shape="SQUARE">Main</entry>
<entry key="i000004" count="7" red="120" green="120" blue="120" shape="SQUARE">New</entry>
<entry key="i000005" count="0" red="220" green="138" blue="221" shape="BLOCK_2">Minor</entry>
<entry key="i000006" count="0" red="220" green="138" blue="221" shape="BLOCK_3">Major</entry>
<entry key="i000007" count="0" red="220" green="138" blue="221" shape="BLOCK_4">Main</entry>
</importance>
</settings>
<content items="16" novelWords="0" notesWords="0" novelChars="0" notesChars="0">
@@ -16,16 +16,16 @@
</lastHandle>
<autoReplace />
<status>
<entry key="s000000" count="5" red="100" green="100" blue="100" shape="SQUARE">New</entry>
<entry key="s000001" count="0" red="200" green="50" blue="0" shape="SQUARE">Note</entry>
<entry key="s000002" count="0" red="200" green="150" blue="0" shape="SQUARE">Draft</entry>
<entry key="s000003" count="0" red="50" green="200" blue="0" shape="SQUARE">Finished</entry>
<entry key="s000000" count="5" red="120" green="120" blue="120" shape="STAR">New</entry>
<entry key="s000001" count="0" red="205" green="171" blue="143" shape="TRIANGLE">Note</entry>
<entry key="s000002" count="0" red="143" green="240" blue="164" shape="CIRCLE_T">Draft</entry>
<entry key="s000003" count="0" red="249" green="240" blue="107" shape="STAR">Finished</entry>
</status>
<importance>
<entry key="i000004" count="7" red="100" green="100" blue="100" shape="SQUARE">New</entry>
<entry key="i000005" count="0" red="200" green="50" blue="0" shape="SQUARE">Minor</entry>
<entry key="i000006" count="0" red="200" green="150" blue="0" shape="SQUARE">Major</entry>
<entry key="i000007" count="0" red="50" green="200" blue="0" shape="SQUARE">Main</entry>
<entry key="i000004" count="7" red="120" green="120" blue="120" shape="SQUARE">New</entry>
<entry key="i000005" count="0" red="220" green="138" blue="221" shape="BLOCK_2">Minor</entry>
<entry key="i000006" count="0" red="220" green="138" blue="221" shape="BLOCK_3">Major</entry>
<entry key="i000007" count="0" red="220" green="138" blue="221" shape="BLOCK_4">Main</entry>
</importance>
</settings>
<content items="12" novelWords="173" notesWords="27" novelChars="1007" notesChars="133">
@@ -16,16 +16,16 @@
</lastHandle>
<autoReplace />
<status>
<entry key="s000000" count="5" red="100" green="100" blue="100" shape="SQUARE">New</entry>
<entry key="s000001" count="0" red="200" green="50" blue="0" shape="SQUARE">Note</entry>
<entry key="s000002" count="0" red="200" green="150" blue="0" shape="SQUARE">Draft</entry>
<entry key="s000003" count="0" red="50" green="200" blue="0" shape="SQUARE">Finished</entry>
<entry key="s000000" count="5" red="120" green="120" blue="120" shape="STAR">New</entry>
<entry key="s000001" count="0" red="205" green="171" blue="143" shape="TRIANGLE">Note</entry>
<entry key="s000002" count="0" red="143" green="240" blue="164" shape="CIRCLE_T">Draft</entry>
<entry key="s000003" count="0" red="249" green="240" blue="107" shape="STAR">Finished</entry>
</status>
<importance>
<entry key="i000004" count="3" red="100" green="100" blue="100" shape="SQUARE">New</entry>
<entry key="i000005" count="0" red="200" green="50" blue="0" shape="SQUARE">Minor</entry>
<entry key="i000006" count="0" red="200" green="150" blue="0" shape="SQUARE">Major</entry>
<entry key="i000007" count="0" red="50" green="200" blue="0" shape="SQUARE">Main</entry>
<entry key="i000004" count="3" red="120" green="120" blue="120" shape="SQUARE">New</entry>
<entry key="i000005" count="0" red="220" green="138" blue="221" shape="BLOCK_2">Minor</entry>
<entry key="i000006" count="0" red="220" green="138" blue="221" shape="BLOCK_3">Major</entry>
<entry key="i000007" count="0" red="220" green="138" blue="221" shape="BLOCK_4">Main</entry>
</importance>
</settings>
<content items="8" novelWords="9" notesWords="0" novelChars="40" notesChars="0">
+11 -2
View File
@@ -37,8 +37,9 @@ from novelwriter.common import (
formatFileFilter, formatInt, formatTime, formatTimeStamp, formatVersion,
fuzzyTime, getFileSize, hexToInt, isHandle, isItemClass, isItemLayout,
isItemType, isListInstance, isTitleTag, jsonEncode, makeFileNameSafe,
minmax, numberToRoman, openExternalPath, readTextFile, simplified,
transferCase, uniqueCompact, xmlElement, xmlIndent, xmlSubElem, yesNo
minmax, numberToRoman, openExternalPath, processDialogSymbols,
readTextFile, simplified, transferCase, uniqueCompact, xmlElement,
xmlIndent, xmlSubElem, yesNo
)
from tests.mocked import causeOSError
@@ -377,6 +378,14 @@ def testBaseCommon_uniqueCompact():
assert uniqueCompact("3 2 1") == "123"
@pytest.mark.base
def testBaseCommon_processDialogSymbols():
"""Test the processDialogSymbols function."""
assert processDialogSymbols("abc") == ""
assert processDialogSymbols("\u00ab\u00ab\u00bb\u00bb") == "\u00ab\u00bb"
assert processDialogSymbols("-\u2013\u2014\u2015") == "\u2013\u2014\u2015"
@pytest.mark.base
def testBaseCommon_elide():
"""Test the elide function."""
+14
View File
@@ -20,6 +20,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
from __future__ import annotations
import datetime
import json
import sys
@@ -189,6 +190,14 @@ def testBaseConfig_Localisation(fncPath, tstPaths):
languages = tstConf.listLanguages(tstConf.LANG_NW)
assert languages == [("en_GB", "British English"), ("fr", "Français")]
# Date Formats
# Checks for bug #2325
ts = datetime.datetime.fromtimestamp(1746370775)
CONFIG._dShortDate = "dd/MM/yyyy"
CONFIG._dShortDateTime = "dd/MM/yyyy HH:mm"
assert CONFIG.localDate(ts) == ts.strftime("%d/%m/%Y")
assert CONFIG.localDateTime(ts) == ts.strftime("%d/%m/%Y %H:%M")
@pytest.mark.base
def testBaseConfig_Methods(fncPath):
@@ -233,6 +242,11 @@ def testBaseConfig_Methods(fncPath):
# Recent Projects
assert isinstance(tstConf.recentProjects, RecentProjects)
# Last Author
assert CONFIG.lastAuthor == ""
CONFIG.setLastAuthor(" Jane Doe ")
assert CONFIG.lastAuthor == "Jane Doe"
@pytest.mark.base
def testBaseConfig_SettersGetters(fncPath):
+10 -1
View File
@@ -23,11 +23,12 @@ from __future__ import annotations
import pytest
from PyQt6.QtCore import QMimeData, QModelIndex, Qt
from PyQt6.QtTest import QAbstractItemModelTester
from novelwriter.common import decodeMimeHandles
from novelwriter.constants import nwConst
from novelwriter.core.item import NWItem
from novelwriter.core.itemmodel import INV_ROOT, NODE_FLAGS, ProjectNode
from novelwriter.core.itemmodel import INV_ROOT, NODE_FLAGS, ProjectModel, ProjectNode
from novelwriter.core.project import NWProject
from novelwriter.enum import nwItemLayout, nwItemType
@@ -253,6 +254,14 @@ def testCoreItemModel_ProjectNode_Data(mockGUI, mockRnd, fncPath):
assert scene.flags() == NODE_FLAGS | Qt.ItemFlag.ItemIsDragEnabled
@pytest.mark.core
def testCoreItemModel_ProjectModel_ModelTest(mockGUI):
"""Run the Qt model tester on the model."""
project = NWProject()
model = ProjectModel(project.tree)
QAbstractItemModelTester(model)
@pytest.mark.core
def testCoreItemModel_ProjectModel_Interface(mockGUI, mockRnd, fncPath):
"""Test the model interface for the project model."""
+8
View File
@@ -23,6 +23,7 @@ from __future__ import annotations
import pytest
from PyQt6.QtCore import QModelIndex, Qt
from PyQt6.QtTest import QAbstractItemModelTester
from novelwriter.core.indexdata import IndexHeading
from novelwriter.core.novelmodel import NovelModel
@@ -32,6 +33,13 @@ from novelwriter.enum import nwNovelExtra
from tests.tools import C, buildTestProject
@pytest.mark.core
def testCoreNovelModel_ModelTest(nwGUI):
"""Run the Qt model tester on the model."""
model = NovelModel()
QAbstractItemModelTester(model)
@pytest.mark.core
def testCoreNovelModel_Interface(nwGUI, fncPath, mockRnd):
"""Test the novel model interface."""
+2 -2
View File
@@ -269,8 +269,8 @@ def testDlgPreferences_Settings(qtbot, monkeypatch, nwGUI, fncPath, tstPaths):
prefs.dialogStyle.setCurrentData(3, 0)
prefs.allowOpenDial.setChecked(False)
prefs.dialogLine.setText("")
prefs.narratorBreak.setText("")
prefs.narratorDialog.setText("")
prefs.narratorBreak.setCurrentData("", "")
prefs.narratorDialog.setCurrentData("", "")
prefs.altDialogOpen.setText("<")
prefs.altDialogClose.setText(">")
prefs.highlightEmph.setChecked(False)
+15 -15
View File
@@ -214,18 +214,18 @@ def testDlgProjSettings_StatusImport(qtbot, monkeypatch, nwGUI, projPath, mockRn
assert update[0][0] == C.sNew
assert update[0][1].name == "New"
assert update[0][1].color == QColor(100, 100, 100)
assert update[0][1].shape == nwStatusShape.SQUARE
assert update[0][1].color == QColor(120, 120, 120)
assert update[0][1].shape == nwStatusShape.STAR
assert update[1][0] == C.sDraft
assert update[1][1].name == "Draft"
assert update[1][1].color == QColor(200, 150, 0)
assert update[1][1].shape == nwStatusShape.SQUARE
assert update[1][1].color == QColor(143, 240, 164)
assert update[1][1].shape == nwStatusShape.CIRCLE_T
assert update[2][0] == C.sFinished
assert update[2][1].name == "Finished"
assert update[2][1].color == QColor(50, 200, 0)
assert update[2][1].shape == nwStatusShape.SQUARE
assert update[2][1].color == QColor(249, 240, 107)
assert update[2][1].shape == nwStatusShape.STAR
assert update[3][0] is None
assert update[3][1].name == "Final"
@@ -289,18 +289,18 @@ def testDlgProjSettings_StatusImport(qtbot, monkeypatch, nwGUI, projPath, mockRn
assert update[0][0] == C.iNew
assert update[0][1].name == "New"
assert update[0][1].color == QColor(100, 100, 100)
assert update[0][1].color == QColor(120, 120, 120)
assert update[0][1].shape == nwStatusShape.SQUARE
assert update[1][0] == C.iMajor
assert update[1][1].name == "Major"
assert update[1][1].color == QColor(200, 150, 0)
assert update[1][1].shape == nwStatusShape.SQUARE
assert update[1][1].color == QColor(220, 138, 221)
assert update[1][1].shape == nwStatusShape.BLOCK_3
assert update[2][0] == C.iMain
assert update[2][1].name == "Main"
assert update[2][1].color == QColor(50, 200, 0)
assert update[2][1].shape == nwStatusShape.SQUARE
assert update[2][1].color == QColor(220, 138, 221)
assert update[2][1].shape == nwStatusShape.BLOCK_4
assert update[3][0] is None
assert update[3][1].name == "Final"
@@ -354,10 +354,10 @@ def testDlgProjSettings_StatusImportExport(qtbot, monkeypatch, nwGUI, projPath,
assert expFile.is_file() is True
assert expFile.read_text().split() == [
"SQUARE,#646464,New",
"SQUARE,#c83200,Note",
"SQUARE,#c89600,Draft",
"SQUARE,#32c800,Finished",
"STAR,#787878,New",
"TRIANGLE,#cdab8f,Note",
"CIRCLE_T,#8ff0a4,Draft",
"STAR,#f9f06b,Finished",
]
# Import Error
+9 -9
View File
@@ -261,7 +261,7 @@ def testToolWritingStats_Filters(qtbot, monkeypatch, nwGUI, projPath, tstPaths):
assert item.text(sessLog.C_COUNT) == f"{200:n}"
# No Novel Files
qtbot.mouseClick(sessLog.incNovel, QtMouseLeft)
qtbot.mouseClick(sessLog.swtIncNovel, QtMouseLeft)
assert sessLog._saveData(sessLog.FMT_JSON)
jsonStats = tstPaths.tmpDir / "sessionStats.json"
@@ -329,8 +329,8 @@ def testToolWritingStats_Filters(qtbot, monkeypatch, nwGUI, projPath, tstPaths):
]
# No Note Files
qtbot.mouseClick(sessLog.incNovel, QtMouseLeft)
qtbot.mouseClick(sessLog.incNotes, QtMouseLeft)
qtbot.mouseClick(sessLog.swtIncNovel, QtMouseLeft)
qtbot.mouseClick(sessLog.swtIncNotes, QtMouseLeft)
assert sessLog._saveData(sessLog.FMT_JSON)
jsonStats = tstPaths.tmpDir / "sessionStats.json"
@@ -398,8 +398,8 @@ def testToolWritingStats_Filters(qtbot, monkeypatch, nwGUI, projPath, tstPaths):
]
# No Negative Entries
qtbot.mouseClick(sessLog.incNotes, QtMouseLeft)
qtbot.mouseClick(sessLog.hideNegative, QtMouseLeft)
qtbot.mouseClick(sessLog.swtIncNotes, QtMouseLeft)
qtbot.mouseClick(sessLog.swtHideNegative, QtMouseLeft)
assert sessLog._saveData(sessLog.FMT_JSON)
jsonStats = tstPaths.tmpDir / "sessionStats.json"
@@ -439,8 +439,8 @@ def testToolWritingStats_Filters(qtbot, monkeypatch, nwGUI, projPath, tstPaths):
]
# Un-hide Zero Entries
qtbot.mouseClick(sessLog.hideNegative, QtMouseLeft)
qtbot.mouseClick(sessLog.hideZeros, QtMouseLeft)
qtbot.mouseClick(sessLog.swtHideNegative, QtMouseLeft)
qtbot.mouseClick(sessLog.swtHideZeros, QtMouseLeft)
assert sessLog._saveData(sessLog.FMT_JSON)
jsonStats = tstPaths.tmpDir / "sessionStats.json"
@@ -526,14 +526,14 @@ def testToolWritingStats_Filters(qtbot, monkeypatch, nwGUI, projPath, tstPaths):
assert item is not None
assert item.text(sessLog.C_IDLE) == "4 %"
qtbot.mouseClick(sessLog.showIdleTime, QtMouseLeft)
qtbot.mouseClick(sessLog.swtShowIdleTime, QtMouseLeft)
item = sessLog.listBox.topLevelItem(7)
assert item is not None
assert item.text(sessLog.C_IDLE) == "00:01:10"
# Group by Day
qtbot.mouseClick(sessLog.groupByDay, QtMouseLeft)
qtbot.mouseClick(sessLog.swtGroupByDay, QtMouseLeft)
assert sessLog._saveData(sessLog.FMT_JSON)
jsonStats = tstPaths.tmpDir / "sessionStats.json"