diff --git a/novelwriter/core/projectxml.py b/novelwriter/core/projectxml.py index a20649d2..47ea748e 100644 --- a/novelwriter/core/projectxml.py +++ b/novelwriter/core/projectxml.py @@ -441,10 +441,10 @@ class ProjectXMLReader: for xEntry in xItem: if xEntry.tag == "entry": key = xEntry.attrib.get("key", None) - red = checkInt(xEntry.attrib.get("red", 0), 0) # Deprecated in 1.5 Rev 6 - green = checkInt(xEntry.attrib.get("green", 0), 0) # Deprecated in 1.5 Rev 6 - blue = checkInt(xEntry.attrib.get("blue", 0), 0) # Deprecated in 1.5 Rev 6 - color = xEntry.attrib.get("color") # Added in 1.5 Rev 6 + red = checkInt(xEntry.attrib.get("red", 0), 0) # Deprecated in 1.5 R6 + green = checkInt(xEntry.attrib.get("green", 0), 0) # Deprecated in 1.5 R6 + blue = checkInt(xEntry.attrib.get("blue", 0), 0) # Deprecated in 1.5 R6 + color = xEntry.attrib.get("color") # Added in 1.5 R6 count = checkInt(xEntry.attrib.get("count", 0), 0) shape = xEntry.attrib.get("shape", "") if color is None: diff --git a/sample/nwProject.nwx b/sample/nwProject.nwx index ae0fee4d..32ed2662 100644 --- a/sample/nwProject.nwx +++ b/sample/nwProject.nwx @@ -1,6 +1,6 @@ - - + + Sample Project Jane Smith @@ -20,20 +20,20 @@ D - New - Notes - Started - 1st Draft - 2nd Draft - 3rd Draft - Finished + New + Notes + Started + 1st Draft + 2nd Draft + 3rd Draft + Finished - None - Background - Minor - Major - Main + None + Background + Minor + Major + Main @@ -58,7 +58,7 @@ Chapter One - + Making a Scene diff --git a/tests/conftest.py b/tests/conftest.py index a2c3ad03..bd66447b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -35,7 +35,7 @@ sys.path.insert(1, str(Path(__file__).parent.parent.absolute())) from novelwriter import CONFIG, SHARED -from tests.mocked import MockGuiMain, MockTheme +from tests.mocked import MockGuiMain from tests.tools import cleanProject _TST_ROOT = Path(__file__).parent @@ -151,12 +151,16 @@ def projPath(fncPath): @pytest.fixture(scope="function") def mockGUI(qtbot, monkeypatch): """Create a mock instance of novelWriter's main GUI class.""" + from novelwriter.gui.theme import GuiTheme + monkeypatch.setattr(QMessageBox, "exec", lambda *a: None) monkeypatch.setattr(QMessageBox, "result", lambda *a: QMessageBox.StandardButton.Yes) gui = MockGuiMain() - theme = MockTheme() + theme = GuiTheme() + theme.loadTheme() monkeypatch.setattr(SHARED, "_gui", gui) monkeypatch.setattr(SHARED, "_theme", theme) + return gui diff --git a/tests/files/nwProject-1.5.nwx b/tests/files/nwProject-1.5.nwx index cd103d11..839b0876 100644 --- a/tests/files/nwProject-1.5.nwx +++ b/tests/files/nwProject-1.5.nwx @@ -1,5 +1,5 @@ - + Sample Project Jane Smith @@ -20,20 +20,20 @@ D - New - Notes - Started - 1st Draft - 2nd Draft - 3rd Draft - Finished + New + Notes + Started + 1st Draft + 2nd Draft + 3rd Draft + Finished - None - Background - Minor - Major - Main + None + Background + Minor + Major + Main diff --git a/tests/lipsum/nwProject.nwx b/tests/lipsum/nwProject.nwx index de32f1f6..f2c7e31c 100644 --- a/tests/lipsum/nwProject.nwx +++ b/tests/lipsum/nwProject.nwx @@ -1,6 +1,6 @@ - - + + Lorem Ipsum lipsum.com @@ -19,16 +19,16 @@ Replace Text 2 - New - Note - Draft - Finished + New + Note + Draft + Finished - New - Minor - Major - Main + New + Minor + Major + Main diff --git a/tests/reference/coreProject_NewFileFolder_nwProject.nwx b/tests/reference/coreProject_NewFileFolder_nwProject.nwx index b244eeb6..d3eec6c6 100644 --- a/tests/reference/coreProject_NewFileFolder_nwProject.nwx +++ b/tests/reference/coreProject_NewFileFolder_nwProject.nwx @@ -1,5 +1,5 @@ - + New Project Jane Doe @@ -16,16 +16,16 @@ - New - Note - Draft - Finished + New + Note + Draft + Finished - New - Minor - Major - Main + New + Minor + Major + Main diff --git a/tests/reference/coreProject_NewRoot_nwProject.nwx b/tests/reference/coreProject_NewRoot_nwProject.nwx index abcfdfb7..4c253097 100644 --- a/tests/reference/coreProject_NewRoot_nwProject.nwx +++ b/tests/reference/coreProject_NewRoot_nwProject.nwx @@ -1,5 +1,5 @@ - + New Project Jane Doe @@ -16,16 +16,16 @@ - New - Note - Draft - Finished + New + Note + Draft + Finished - New - Minor - Major - Main + New + Minor + Major + Main diff --git a/tests/reference/coreTools_DocDuplicator_nwProject.nwx b/tests/reference/coreTools_DocDuplicator_nwProject.nwx index 9b0d2071..2fb52c05 100644 --- a/tests/reference/coreTools_DocDuplicator_nwProject.nwx +++ b/tests/reference/coreTools_DocDuplicator_nwProject.nwx @@ -1,5 +1,5 @@ - + New Project Jane Doe @@ -16,16 +16,16 @@ - New - Note - Draft - Finished + New + Note + Draft + Finished - New - Minor - Major - Main + New + Minor + Major + Main diff --git a/tests/reference/coreTools_ProjectBuilderA_nwProject.nwx b/tests/reference/coreTools_ProjectBuilderA_nwProject.nwx index 296b8172..5b7cbbab 100644 --- a/tests/reference/coreTools_ProjectBuilderA_nwProject.nwx +++ b/tests/reference/coreTools_ProjectBuilderA_nwProject.nwx @@ -1,5 +1,5 @@ - + Test Project A Jane Doe @@ -16,16 +16,16 @@ - New - Note - Draft - Finished + New + Note + Draft + Finished - New - Minor - Major - Main + New + Minor + Major + Main diff --git a/tests/reference/coreTools_ProjectBuilderB_nwProject.nwx b/tests/reference/coreTools_ProjectBuilderB_nwProject.nwx index 531aea22..83362eb3 100644 --- a/tests/reference/coreTools_ProjectBuilderB_nwProject.nwx +++ b/tests/reference/coreTools_ProjectBuilderB_nwProject.nwx @@ -1,5 +1,5 @@ - + Test Project B Jane Doe @@ -16,16 +16,16 @@ - New - Note - Draft - Finished + New + Note + Draft + Finished - New - Minor - Major - Main + New + Minor + Major + Main diff --git a/tests/reference/fmtToDocX_SaveDocument_core.xml b/tests/reference/fmtToDocX_SaveDocument_core.xml index 3a0d34b6..25a58621 100644 --- a/tests/reference/fmtToDocX_SaveDocument_core.xml +++ b/tests/reference/fmtToDocX_SaveDocument_core.xml @@ -1,10 +1,10 @@ - 2025-04-29T22:46:36 - 2025-04-29T22:46:36 + 2025-06-12T19:20:06 + 2025-06-12T19:20:06 lipsum.com Lorem Ipsum en_GB - 52 + 54 lipsum.com diff --git a/tests/reference/guiEditor_Main_Final_nwProject.nwx b/tests/reference/guiEditor_Main_Final_nwProject.nwx index 21078178..d415b195 100644 --- a/tests/reference/guiEditor_Main_Final_nwProject.nwx +++ b/tests/reference/guiEditor_Main_Final_nwProject.nwx @@ -1,5 +1,5 @@ - + New Project Jane Doe @@ -16,16 +16,16 @@ - New - Note - Draft - Finished + New + Note + Draft + Finished - New - Minor - Major - Main + New + Minor + Major + Main diff --git a/tests/reference/guiEditor_Main_Initial_nwProject.nwx b/tests/reference/guiEditor_Main_Initial_nwProject.nwx index 1f3260da..bb69bd02 100644 --- a/tests/reference/guiEditor_Main_Initial_nwProject.nwx +++ b/tests/reference/guiEditor_Main_Initial_nwProject.nwx @@ -1,5 +1,5 @@ - + New Project Jane Doe @@ -16,16 +16,16 @@ - New - Note - Draft - Finished + New + Note + Draft + Finished - New - Minor - Major - Main + New + Minor + Major + Main diff --git a/tests/reference/projectXML_ReadLegacy10.nwx b/tests/reference/projectXML_ReadLegacy10.nwx index cc0c7d88..3a59d7e7 100644 --- a/tests/reference/projectXML_ReadLegacy10.nwx +++ b/tests/reference/projectXML_ReadLegacy10.nwx @@ -1,5 +1,5 @@ - + Sample Project Jay Doh @@ -20,19 +20,19 @@ D - New - Notes - Started - 1st Draft - 2nd Draft - 3rd Draft - Finished + New + Notes + Started + 1st Draft + 2nd Draft + 3rd Draft + Finished - None - Minor - Major - Main + None + Minor + Major + Main diff --git a/tests/reference/projectXML_ReadLegacy11.nwx b/tests/reference/projectXML_ReadLegacy11.nwx index 0ea370fb..bd4bc6f5 100644 --- a/tests/reference/projectXML_ReadLegacy11.nwx +++ b/tests/reference/projectXML_ReadLegacy11.nwx @@ -1,5 +1,5 @@ - + Sample Project Jay Doh @@ -20,19 +20,19 @@ D - New - Notes - Started - 1st Draft - 2nd Draft - 3rd Draft - Finished + New + Notes + Started + 1st Draft + 2nd Draft + 3rd Draft + Finished - None - Minor - Major - Main + None + Minor + Major + Main diff --git a/tests/reference/projectXML_ReadLegacy12.nwx b/tests/reference/projectXML_ReadLegacy12.nwx index bac7fb3a..7a949b06 100644 --- a/tests/reference/projectXML_ReadLegacy12.nwx +++ b/tests/reference/projectXML_ReadLegacy12.nwx @@ -1,5 +1,5 @@ - + Sample Project Jay Doh @@ -20,19 +20,19 @@ D - New - Notes - Started - 1st Draft - 2nd Draft - 3rd Draft - Finished + New + Notes + Started + 1st Draft + 2nd Draft + 3rd Draft + Finished - None - Minor - Major - Main + None + Minor + Major + Main diff --git a/tests/reference/projectXML_ReadLegacy13.nwx b/tests/reference/projectXML_ReadLegacy13.nwx index 1fb96f5e..c9fc13e6 100644 --- a/tests/reference/projectXML_ReadLegacy13.nwx +++ b/tests/reference/projectXML_ReadLegacy13.nwx @@ -1,5 +1,5 @@ - + Sample Project Jay Doh @@ -20,19 +20,19 @@ D - New - Notes - Started - 1st Draft - 2nd Draft - 3rd Draft - Finished + New + Notes + Started + 1st Draft + 2nd Draft + 3rd Draft + Finished - None - Minor - Major - Main + None + Minor + Major + Main diff --git a/tests/reference/projectXML_ReadLegacy14.nwx b/tests/reference/projectXML_ReadLegacy14.nwx index 3c763d27..b123a490 100644 --- a/tests/reference/projectXML_ReadLegacy14.nwx +++ b/tests/reference/projectXML_ReadLegacy14.nwx @@ -1,5 +1,5 @@ - + Sample Project Jay Doh @@ -20,19 +20,19 @@ D - New - Notes - Started - 1st Draft - 2nd Draft - 3rd Draft - Finished + New + Notes + Started + 1st Draft + 2nd Draft + 3rd Draft + Finished - None - Minor - Major - Main + None + Minor + Major + Main diff --git a/tests/test_core/test_core_item.py b/tests/test_core/test_core_item.py index ad93f7db..f6cd4278 100644 --- a/tests/test_core/test_core_item.py +++ b/tests/test_core/test_core_item.py @@ -547,8 +547,8 @@ def testCoreItem_ClassDefaults(mockGUI): def testCoreItem_PackUnpack(mockGUI, caplog, mockRnd): """Test packing and unpacking entries for the NWItem class.""" project = NWProject() - project.data.itemStatus.add(None, "New", (100, 100, 100), "SQUARE", 0) - project.data.itemImport.add(None, "New", (100, 100, 100), "SQUARE", 0) + project.data.itemStatus.add(None, "New", "#646464", "SQUARE", 0) + project.data.itemImport.add(None, "New", "#646464", "SQUARE", 0) # Invalid item = NWItem(project, "0000000000000") diff --git a/tests/test_core/test_core_projectxml.py b/tests/test_core/test_core_projectxml.py index 3021c7c4..ebccbbfa 100644 --- a/tests/test_core/test_core_projectxml.py +++ b/tests/test_core/test_core_projectxml.py @@ -27,12 +27,11 @@ from shutil import copyfile import pytest -from PyQt6.QtGui import QColor - from novelwriter.constants import nwFiles from novelwriter.core.item import NWItem from novelwriter.core.projectdata import NWProjectData from novelwriter.core.projectxml import ProjectXMLReader, ProjectXMLWriter, XMLReadState +from novelwriter.core.status import CUSTOM_COL from novelwriter.enum import nwStatusShape from tests.mocked import causeOSError @@ -137,7 +136,7 @@ def testCoreProjectXML_ReadCurrent(monkeypatch, mockGUI, tstPaths, fncPath): assert xmlReader.state == XMLReadState.PARSED_OK assert xmlReader.xmlRoot == "novelWriterXML" assert xmlReader.xmlVersion == 0x0105 - assert xmlReader.xmlRevision == 5 + assert xmlReader.xmlRevision == 6 assert xmlReader.appVersion == "2.7b1" assert xmlReader.hexVersion == 0x020700b1 @@ -173,19 +172,31 @@ def testCoreProjectXML_ReadCurrent(monkeypatch, mockGUI, tstPaths, fncPath): assert data.itemImport["i2d7a54"].name == "Major" assert data.itemImport["i56be10"].name == "Main" - assert data.itemStatus["sf12341"].color == QColor(100, 100, 100) - assert data.itemStatus["sf24ce6"].color == QColor(200, 50, 0) - assert data.itemStatus["sc24b8f"].color == QColor(182, 60, 0) - assert data.itemStatus["s90e6c9"].color == QColor(193, 129, 0) - assert data.itemStatus["sd51c5b"].color == QColor(193, 129, 0) - assert data.itemStatus["s8ae72a"].color == QColor(193, 129, 0) - assert data.itemStatus["s78ea90"].color == QColor(58, 180, 58) + assert data.itemStatus["sf12341"].color.getRgb() == (100, 100, 100, 255) + assert data.itemStatus["sf24ce6"].color.getRgb() == (200, 50, 0, 255) + assert data.itemStatus["sc24b8f"].color.getRgb() == (182, 60, 0, 255) + assert data.itemStatus["s90e6c9"].color.getRgb() == (193, 129, 0, 255) + assert data.itemStatus["sd51c5b"].color.getRgb() == (193, 129, 0, 255) + assert data.itemStatus["s8ae72a"].color.getRgb() == (193, 129, 0, 255) + assert data.itemStatus["s78ea90"].color.getRgb() == (58, 180, 58, 255) - assert data.itemImport["ia857f0"].color == QColor(100, 100, 100) - assert data.itemImport["i4a1d39"].color == QColor(220, 138, 221) - assert data.itemImport["icfb3a5"].color == QColor(220, 138, 221) - assert data.itemImport["i2d7a54"].color == QColor(220, 138, 221) - assert data.itemImport["i56be10"].color == QColor(220, 138, 221) + assert data.itemImport["ia857f0"].color.getRgb() == (100, 100, 100, 255) + assert data.itemImport["icfb3a5"].color.getRgb() == (220, 138, 221, 255) + assert data.itemImport["i2d7a54"].color.getRgb() == (220, 138, 221, 255) + assert data.itemImport["i56be10"].color.getRgb() == (220, 138, 221, 255) + + assert data.itemStatus["sf12341"].theme == CUSTOM_COL + assert data.itemStatus["sf24ce6"].theme == CUSTOM_COL + assert data.itemStatus["sc24b8f"].theme == CUSTOM_COL + assert data.itemStatus["s90e6c9"].theme == CUSTOM_COL + assert data.itemStatus["sd51c5b"].theme == CUSTOM_COL + assert data.itemStatus["s8ae72a"].theme == CUSTOM_COL + assert data.itemStatus["s78ea90"].theme == CUSTOM_COL + + assert data.itemImport["ia857f0"].theme == CUSTOM_COL + assert data.itemImport["icfb3a5"].theme == CUSTOM_COL + assert data.itemImport["i2d7a54"].theme == CUSTOM_COL + assert data.itemImport["i56be10"].theme == CUSTOM_COL assert data.itemStatus["sf12341"].shape == nwStatusShape.SQUARE assert data.itemStatus["sf24ce6"].shape == nwStatusShape.SQUARE @@ -305,18 +316,31 @@ def testCoreProjectXML_ReadLegacy10(tstPaths, fncPath, mockGUI, mockRnd): assert data.itemImport["i000009"].name == "Major" assert data.itemImport["i00000a"].name == "Main" - assert data.itemStatus["s000000"].color == QColor(100, 100, 100) - assert data.itemStatus["s000001"].color == QColor(200, 50, 0) - assert data.itemStatus["s000002"].color == QColor(182, 60, 0) - assert data.itemStatus["s000003"].color == QColor(193, 129, 0) - assert data.itemStatus["s000004"].color == QColor(193, 129, 0) - assert data.itemStatus["s000005"].color == QColor(193, 129, 0) - assert data.itemStatus["s000006"].color == QColor(58, 180, 58) + assert data.itemStatus["s000000"].color.getRgb() == (100, 100, 100, 255) + assert data.itemStatus["s000001"].color.getRgb() == (200, 50, 0, 255) + assert data.itemStatus["s000002"].color.getRgb() == (182, 60, 0, 255) + assert data.itemStatus["s000003"].color.getRgb() == (193, 129, 0, 255) + assert data.itemStatus["s000004"].color.getRgb() == (193, 129, 0, 255) + assert data.itemStatus["s000005"].color.getRgb() == (193, 129, 0, 255) + assert data.itemStatus["s000006"].color.getRgb() == (58, 180, 58, 255) - assert data.itemImport["i000007"].color == QColor(100, 100, 100) - assert data.itemImport["i000008"].color == QColor(0, 122, 188) - assert data.itemImport["i000009"].color == QColor(21, 0, 180) - assert data.itemImport["i00000a"].color == QColor(117, 0, 175) + assert data.itemImport["i000007"].color.getRgb() == (100, 100, 100, 255) + assert data.itemImport["i000008"].color.getRgb() == (0, 122, 188, 255) + assert data.itemImport["i000009"].color.getRgb() == (21, 0, 180, 255) + assert data.itemImport["i00000a"].color.getRgb() == (117, 0, 175, 255) + + assert data.itemStatus["s000000"].theme == CUSTOM_COL + assert data.itemStatus["s000001"].theme == CUSTOM_COL + assert data.itemStatus["s000002"].theme == CUSTOM_COL + assert data.itemStatus["s000003"].theme == CUSTOM_COL + assert data.itemStatus["s000004"].theme == CUSTOM_COL + assert data.itemStatus["s000005"].theme == CUSTOM_COL + assert data.itemStatus["s000006"].theme == CUSTOM_COL + + assert data.itemImport["i000007"].theme == CUSTOM_COL + assert data.itemImport["i000008"].theme == CUSTOM_COL + assert data.itemImport["i000009"].theme == CUSTOM_COL + assert data.itemImport["i00000a"].theme == CUSTOM_COL assert data.itemStatus["s000000"].shape == nwStatusShape.SQUARE assert data.itemStatus["s000001"].shape == nwStatusShape.SQUARE @@ -450,18 +474,31 @@ def testCoreProjectXML_ReadLegacy11(tstPaths, fncPath, mockGUI, mockRnd): assert data.itemImport["i000009"].name == "Major" assert data.itemImport["i00000a"].name == "Main" - assert data.itemStatus["s000000"].color == QColor(100, 100, 100) - assert data.itemStatus["s000001"].color == QColor(200, 50, 0) - assert data.itemStatus["s000002"].color == QColor(182, 60, 0) - assert data.itemStatus["s000003"].color == QColor(193, 129, 0) - assert data.itemStatus["s000004"].color == QColor(193, 129, 0) - assert data.itemStatus["s000005"].color == QColor(193, 129, 0) - assert data.itemStatus["s000006"].color == QColor(58, 180, 58) + assert data.itemStatus["s000000"].color.getRgb() == (100, 100, 100, 255) + assert data.itemStatus["s000001"].color.getRgb() == (200, 50, 0, 255) + assert data.itemStatus["s000002"].color.getRgb() == (182, 60, 0, 255) + assert data.itemStatus["s000003"].color.getRgb() == (193, 129, 0, 255) + assert data.itemStatus["s000004"].color.getRgb() == (193, 129, 0, 255) + assert data.itemStatus["s000005"].color.getRgb() == (193, 129, 0, 255) + assert data.itemStatus["s000006"].color.getRgb() == (58, 180, 58, 255) - assert data.itemImport["i000007"].color == QColor(100, 100, 100) - assert data.itemImport["i000008"].color == QColor(0, 122, 188) - assert data.itemImport["i000009"].color == QColor(21, 0, 180) - assert data.itemImport["i00000a"].color == QColor(117, 0, 175) + assert data.itemImport["i000007"].color.getRgb() == (100, 100, 100, 255) + assert data.itemImport["i000008"].color.getRgb() == (0, 122, 188, 255) + assert data.itemImport["i000009"].color.getRgb() == (21, 0, 180, 255) + assert data.itemImport["i00000a"].color.getRgb() == (117, 0, 175, 255) + + assert data.itemStatus["s000000"].theme == CUSTOM_COL + assert data.itemStatus["s000001"].theme == CUSTOM_COL + assert data.itemStatus["s000002"].theme == CUSTOM_COL + assert data.itemStatus["s000003"].theme == CUSTOM_COL + assert data.itemStatus["s000004"].theme == CUSTOM_COL + assert data.itemStatus["s000005"].theme == CUSTOM_COL + assert data.itemStatus["s000006"].theme == CUSTOM_COL + + assert data.itemImport["i000007"].theme == CUSTOM_COL + assert data.itemImport["i000008"].theme == CUSTOM_COL + assert data.itemImport["i000009"].theme == CUSTOM_COL + assert data.itemImport["i00000a"].theme == CUSTOM_COL assert data.itemStatus["s000000"].shape == nwStatusShape.SQUARE assert data.itemStatus["s000001"].shape == nwStatusShape.SQUARE @@ -595,18 +632,31 @@ def testCoreProjectXML_ReadLegacy12(tstPaths, fncPath, mockGUI, mockRnd): assert data.itemImport["i000009"].name == "Major" assert data.itemImport["i00000a"].name == "Main" - assert data.itemStatus["s000000"].color == QColor(100, 100, 100) - assert data.itemStatus["s000001"].color == QColor(200, 50, 0) - assert data.itemStatus["s000002"].color == QColor(182, 60, 0) - assert data.itemStatus["s000003"].color == QColor(193, 129, 0) - assert data.itemStatus["s000004"].color == QColor(193, 129, 0) - assert data.itemStatus["s000005"].color == QColor(193, 129, 0) - assert data.itemStatus["s000006"].color == QColor(58, 180, 58) + assert data.itemStatus["s000000"].color.getRgb() == (100, 100, 100, 255) + assert data.itemStatus["s000001"].color.getRgb() == (200, 50, 0, 255) + assert data.itemStatus["s000002"].color.getRgb() == (182, 60, 0, 255) + assert data.itemStatus["s000003"].color.getRgb() == (193, 129, 0, 255) + assert data.itemStatus["s000004"].color.getRgb() == (193, 129, 0, 255) + assert data.itemStatus["s000005"].color.getRgb() == (193, 129, 0, 255) + assert data.itemStatus["s000006"].color.getRgb() == (58, 180, 58, 255) - assert data.itemImport["i000007"].color == QColor(100, 100, 100) - assert data.itemImport["i000008"].color == QColor(0, 122, 188) - assert data.itemImport["i000009"].color == QColor(21, 0, 180) - assert data.itemImport["i00000a"].color == QColor(117, 0, 175) + assert data.itemImport["i000007"].color.getRgb() == (100, 100, 100, 255) + assert data.itemImport["i000008"].color.getRgb() == (0, 122, 188, 255) + assert data.itemImport["i000009"].color.getRgb() == (21, 0, 180, 255) + assert data.itemImport["i00000a"].color.getRgb() == (117, 0, 175, 255) + + assert data.itemStatus["s000000"].theme == CUSTOM_COL + assert data.itemStatus["s000001"].theme == CUSTOM_COL + assert data.itemStatus["s000002"].theme == CUSTOM_COL + assert data.itemStatus["s000003"].theme == CUSTOM_COL + assert data.itemStatus["s000004"].theme == CUSTOM_COL + assert data.itemStatus["s000005"].theme == CUSTOM_COL + assert data.itemStatus["s000006"].theme == CUSTOM_COL + + assert data.itemImport["i000007"].theme == CUSTOM_COL + assert data.itemImport["i000008"].theme == CUSTOM_COL + assert data.itemImport["i000009"].theme == CUSTOM_COL + assert data.itemImport["i00000a"].theme == CUSTOM_COL assert data.itemStatus["s000000"].shape == nwStatusShape.SQUARE assert data.itemStatus["s000001"].shape == nwStatusShape.SQUARE @@ -743,18 +793,31 @@ def testCoreProjectXML_ReadLegacy13(tstPaths, fncPath, mockGUI, mockRnd): assert data.itemImport["i000009"].name == "Major" assert data.itemImport["i00000a"].name == "Main" - assert data.itemStatus["s000000"].color == QColor(100, 100, 100) - assert data.itemStatus["s000001"].color == QColor(200, 50, 0) - assert data.itemStatus["s000002"].color == QColor(182, 60, 0) - assert data.itemStatus["s000003"].color == QColor(193, 129, 0) - assert data.itemStatus["s000004"].color == QColor(193, 129, 0) - assert data.itemStatus["s000005"].color == QColor(193, 129, 0) - assert data.itemStatus["s000006"].color == QColor(58, 180, 58) + assert data.itemStatus["s000000"].color.getRgb() == (100, 100, 100, 255) + assert data.itemStatus["s000001"].color.getRgb() == (200, 50, 0, 255) + assert data.itemStatus["s000002"].color.getRgb() == (182, 60, 0, 255) + assert data.itemStatus["s000003"].color.getRgb() == (193, 129, 0, 255) + assert data.itemStatus["s000004"].color.getRgb() == (193, 129, 0, 255) + assert data.itemStatus["s000005"].color.getRgb() == (193, 129, 0, 255) + assert data.itemStatus["s000006"].color.getRgb() == (58, 180, 58, 255) - assert data.itemImport["i000007"].color == QColor(100, 100, 100) - assert data.itemImport["i000008"].color == QColor(0, 122, 188) - assert data.itemImport["i000009"].color == QColor(21, 0, 180) - assert data.itemImport["i00000a"].color == QColor(117, 0, 175) + assert data.itemImport["i000007"].color.getRgb() == (100, 100, 100, 255) + assert data.itemImport["i000008"].color.getRgb() == (0, 122, 188, 255) + assert data.itemImport["i000009"].color.getRgb() == (21, 0, 180, 255) + assert data.itemImport["i00000a"].color.getRgb() == (117, 0, 175, 255) + + assert data.itemStatus["s000000"].theme == CUSTOM_COL + assert data.itemStatus["s000001"].theme == CUSTOM_COL + assert data.itemStatus["s000002"].theme == CUSTOM_COL + assert data.itemStatus["s000003"].theme == CUSTOM_COL + assert data.itemStatus["s000004"].theme == CUSTOM_COL + assert data.itemStatus["s000005"].theme == CUSTOM_COL + assert data.itemStatus["s000006"].theme == CUSTOM_COL + + assert data.itemImport["i000007"].theme == CUSTOM_COL + assert data.itemImport["i000008"].theme == CUSTOM_COL + assert data.itemImport["i000009"].theme == CUSTOM_COL + assert data.itemImport["i00000a"].theme == CUSTOM_COL assert data.itemStatus["s000000"].shape == nwStatusShape.SQUARE assert data.itemStatus["s000001"].shape == nwStatusShape.SQUARE @@ -891,18 +954,31 @@ def testCoreProjectXML_ReadLegacy14(tstPaths, fncPath, mockGUI, mockRnd): assert data.itemImport["i2d7a54"].name == "Major" assert data.itemImport["i56be10"].name == "Main" - assert data.itemStatus["sf12341"].color == QColor(100, 100, 100) - assert data.itemStatus["sf24ce6"].color == QColor(200, 50, 0) - assert data.itemStatus["sc24b8f"].color == QColor(182, 60, 0) - assert data.itemStatus["s90e6c9"].color == QColor(193, 129, 0) - assert data.itemStatus["sd51c5b"].color == QColor(193, 129, 0) - assert data.itemStatus["s8ae72a"].color == QColor(193, 129, 0) - assert data.itemStatus["s78ea90"].color == QColor(58, 180, 58) + assert data.itemStatus["sf12341"].color.getRgb() == (100, 100, 100, 255) + assert data.itemStatus["sf24ce6"].color.getRgb() == (200, 50, 0, 255) + assert data.itemStatus["sc24b8f"].color.getRgb() == (182, 60, 0, 255) + assert data.itemStatus["s90e6c9"].color.getRgb() == (193, 129, 0, 255) + assert data.itemStatus["sd51c5b"].color.getRgb() == (193, 129, 0, 255) + assert data.itemStatus["s8ae72a"].color.getRgb() == (193, 129, 0, 255) + assert data.itemStatus["s78ea90"].color.getRgb() == (58, 180, 58, 255) - assert data.itemImport["ia857f0"].color == QColor(100, 100, 100) - assert data.itemImport["icfb3a5"].color == QColor(0, 122, 188) - assert data.itemImport["i2d7a54"].color == QColor(21, 0, 180) - assert data.itemImport["i56be10"].color == QColor(117, 0, 175) + assert data.itemImport["ia857f0"].color.getRgb() == (100, 100, 100, 255) + assert data.itemImport["icfb3a5"].color.getRgb() == (0, 122, 188, 255) + assert data.itemImport["i2d7a54"].color.getRgb() == (21, 0, 180, 255) + assert data.itemImport["i56be10"].color.getRgb() == (117, 0, 175, 255) + + assert data.itemStatus["sf12341"].theme == CUSTOM_COL + assert data.itemStatus["sf24ce6"].theme == CUSTOM_COL + assert data.itemStatus["sc24b8f"].theme == CUSTOM_COL + assert data.itemStatus["s90e6c9"].theme == CUSTOM_COL + assert data.itemStatus["sd51c5b"].theme == CUSTOM_COL + assert data.itemStatus["s8ae72a"].theme == CUSTOM_COL + assert data.itemStatus["s78ea90"].theme == CUSTOM_COL + + assert data.itemImport["ia857f0"].theme == CUSTOM_COL + assert data.itemImport["icfb3a5"].theme == CUSTOM_COL + assert data.itemImport["i2d7a54"].theme == CUSTOM_COL + assert data.itemImport["i56be10"].theme == CUSTOM_COL assert data.itemStatus["sf12341"].shape == nwStatusShape.SQUARE assert data.itemStatus["sf24ce6"].shape == nwStatusShape.SQUARE diff --git a/tests/test_core/test_core_status.py b/tests/test_core/test_core_status.py index dd6b18a5..3b5e80b8 100644 --- a/tests/test_core/test_core_status.py +++ b/tests/test_core/test_core_status.py @@ -24,7 +24,7 @@ import pytest from PyQt6.QtGui import QColor, QIcon -from novelwriter.core.status import NWStatus, StatusEntry, _ShapeCache +from novelwriter.core.status import CUSTOM_COL, NWStatus, StatusEntry, _ShapeCache from novelwriter.enum import nwStatusShape from tests.tools import C @@ -38,11 +38,12 @@ def testCoreStatus_StatusEntry(): """Test the StatusEntry class.""" color = QColor(255, 0, 0) icon = NWStatus.createIcon(24, color, nwStatusShape.CIRCLE) - entry = StatusEntry("Test", color, nwStatusShape.CIRCLE, icon, 42) + entry = StatusEntry("Test", color, CUSTOM_COL, nwStatusShape.CIRCLE, icon, 42) # Check values assert entry.name == "Test" assert entry.color is color + assert entry.theme == CUSTOM_COL assert entry.shape == nwStatusShape.CIRCLE assert entry.icon is icon assert entry.count == 42 @@ -55,6 +56,7 @@ def testCoreStatus_StatusEntry(): assert other.name == "Test" assert other.color is not color # Not the same object assert other.color == color # But same colours + assert entry.theme == CUSTOM_COL assert other.shape == nwStatusShape.CIRCLE assert other.icon is not icon # Not the same icon, but a copy assert other.count == 42 @@ -73,14 +75,14 @@ def testCoreStatus_Internal(mockGUI, mockRnd): assert nStatus._newKey() == statusKeys[1] # Key collision, should move to key 3 - nStatus.add(statusKeys[2], "Crash", (0, 0, 0), "SQUARE", 0) + nStatus.add(statusKeys[2], "Crash", "#000000", "SQUARE", 0) assert nStatus._newKey() == statusKeys[3] assert nImport._newKey() == importKeys[0] assert nImport._newKey() == importKeys[1] # Key collision, should move to key 3 - nImport.add(importKeys[2], "Crash", (0, 0, 0), "SQUARE", 0) + nImport.add(importKeys[2], "Crash", "#000000", "SQUARE", 0) assert nImport._newKey() == importKeys[3] # Check Key @@ -119,14 +121,14 @@ def testCoreStatus_Internal(mockGUI, mockRnd): def testCoreStatus_Iterator(mockGUI, mockRnd): """Test the iterator functions of the NWStatus class.""" nStatus = NWStatus(NWStatus.STATUS) - nStatus.add(None, "New", (100, 100, 100), "SQUARE", 0) - nStatus.add(None, "Note", (200, 50, 0), "CIRCLE", 1) - nStatus.add(None, "Draft", (200, 150, 0), "SQUARE", 2) - nStatus.add(None, "Finished", (50, 200, 0), "CIRCLE", 3) + nStatus.add(None, "New", "#646464", "SQUARE", 0) + nStatus.add(None, "Note", "#ff3f00", "CIRCLE", 1) + nStatus.add(None, "Draft", "#ffaf00", "SQUARE", 2) + nStatus.add(None, "Finished", "#3fff00", "CIRCLE", 3) # Direct access entry = nStatus[statusKeys[0]] - assert entry.color == QColor(100, 100, 100) + assert entry.color.getRgb() == (100, 100, 100, 255) assert entry.name == "New" assert entry.count == 0 assert isinstance(entry.icon, QIcon) @@ -146,8 +148,8 @@ def testCoreStatus_Iterator(mockGUI, mockRnd): ] # Content : Colours - assert [e.color for _, e in nStatus.iterItems()] == [ - QColor(100, 100, 100), QColor(200, 50, 0), QColor(200, 150, 0), QColor(50, 200, 0) + assert [e.color.getRgb() for _, e in nStatus.iterItems()] == [ + (100, 100, 100, 255), (255, 63, 0, 255), (255, 175, 0, 255), (63, 255, 0, 255) ] # Content : Shape @@ -168,27 +170,31 @@ def testCoreStatus_Entries(mockGUI, mockRnd): # === # Has a key - nStatus.add(statusKeys[0], "Entry 1", (200, 100, 50), "SQUARE", 0) + nStatus.add(statusKeys[0], "Entry 1", "200, 100, 50", "SQUARE", 0) assert nStatus[statusKeys[0]].name == "Entry 1" - assert nStatus[statusKeys[0]].color == QColor(200, 100, 50) + assert nStatus[statusKeys[0]].color.getRgb() == (200, 100, 50, 255) + assert nStatus[statusKeys[0]].theme == CUSTOM_COL assert nStatus[statusKeys[0]].shape == nwStatusShape.SQUARE # Doesn't have a key - nStatus.add(None, "Entry 2", (210, 110, 60), "SQUARE", 0) + nStatus.add(None, "Entry 2", "210, 110, 60", "SQUARE", 0) assert nStatus[statusKeys[1]].name == "Entry 2" - assert nStatus[statusKeys[1]].color == QColor(210, 110, 60) + assert nStatus[statusKeys[1]].color.getRgb() == (210, 110, 60, 255) + assert nStatus[statusKeys[1]].theme == CUSTOM_COL assert nStatus[statusKeys[1]].shape == nwStatusShape.SQUARE # Wrong colour spec, unknown shape - nStatus.add(None, "Entry 3", "what?", "", 0) # type: ignore + nStatus.add(None, "Entry 3", "what?", "", 0) assert nStatus[statusKeys[2]].name == "Entry 3" - assert nStatus[statusKeys[2]].color == QColor(100, 100, 100) + assert nStatus[statusKeys[2]].color.getRgb() == (0, 0, 0, 255) + assert nStatus[statusKeys[2]].theme == CUSTOM_COL assert nStatus[statusKeys[2]].shape == nwStatusShape.SQUARE - # Wrong colour count - nStatus.add(None, "Entry 4", (10, 20), "CIRCLE", 0) # type: ignore + # Wrong colour definition + nStatus.add(None, "Entry 4", "#stuff#", "CIRCLE", 0) assert nStatus[statusKeys[3]].name == "Entry 4" - assert nStatus[statusKeys[3]].color == QColor(100, 100, 100) + assert nStatus[statusKeys[3]].color.getRgb() == (0, 0, 0, 255) + assert nStatus[statusKeys[3]].theme == CUSTOM_COL assert nStatus[statusKeys[3]].shape == nwStatusShape.CIRCLE # Check @@ -202,8 +208,6 @@ def testCoreStatus_Entries(mockGUI, mockRnd): assert nStatus.check("s987654") == statusKeys[0] # Name Access - # =========== - assert nStatus[statusKeys[0]].name == "Entry 1" assert nStatus[statusKeys[1]].name == "Entry 2" assert nStatus[statusKeys[2]].name == "Entry 3" @@ -211,17 +215,20 @@ def testCoreStatus_Entries(mockGUI, mockRnd): assert nStatus["blablabla"].name == "Entry 1" # Colour Access - # ============= + assert nStatus[statusKeys[0]].color.getRgb() == (200, 100, 50, 255) + assert nStatus[statusKeys[1]].color.getRgb() == (210, 110, 60, 255) + assert nStatus[statusKeys[2]].color.getRgb() == (0, 0, 0, 255) + assert nStatus[statusKeys[3]].color.getRgb() == (0, 0, 0, 255) + assert nStatus["blablabla"].color.getRgb() == (200, 100, 50, 255) - assert nStatus[statusKeys[0]].color == QColor(200, 100, 50) - assert nStatus[statusKeys[1]].color == QColor(210, 110, 60) - assert nStatus[statusKeys[2]].color == QColor(100, 100, 100) - assert nStatus[statusKeys[3]].color == QColor(100, 100, 100) - assert nStatus["blablabla"].color == QColor(200, 100, 50) + # Theme Access + assert nStatus[statusKeys[0]].theme == CUSTOM_COL + assert nStatus[statusKeys[1]].theme == CUSTOM_COL + assert nStatus[statusKeys[2]].theme == CUSTOM_COL + assert nStatus[statusKeys[3]].theme == CUSTOM_COL + assert nStatus["blablabla"].theme == CUSTOM_COL # Icon Access - # =========== - assert isinstance(nStatus[statusKeys[0]].icon, QIcon) assert isinstance(nStatus[statusKeys[1]].icon, QIcon) assert isinstance(nStatus[statusKeys[2]].icon, QIcon) @@ -229,8 +236,6 @@ def testCoreStatus_Entries(mockGUI, mockRnd): assert isinstance(nStatus["blablabla"].icon, QIcon) # Shape Access - # ============ - assert nStatus[statusKeys[0]].shape == nwStatusShape.SQUARE assert nStatus[statusKeys[1]].shape == nwStatusShape.SQUARE assert nStatus[statusKeys[2]].shape == nwStatusShape.SQUARE @@ -322,10 +327,10 @@ def testCoreStatus_Entries(mockGUI, mockRnd): def testCoreStatus_Pack(mockGUI, mockRnd): """Test data packing of the NWStatus class.""" nStatus = NWStatus(NWStatus.STATUS) - nStatus.add(None, "New", (100, 100, 100), "SQUARE", 0) - nStatus.add(None, "Note", (200, 50, 0), "CIRCLE", 0) - nStatus.add(None, "Draft", (200, 150, 0), "SQUARE", 0) - nStatus.add(None, "Finished", (50, 200, 0), "SQUARE", 0) + nStatus.add(None, "New", "#646464", "SQUARE", 0) + nStatus.add(None, "Note", "#c83200", "CIRCLE", 0) + nStatus.add(None, "Draft", "#c89600", "SQUARE", 0) + nStatus.add(None, "Finished", "#32c800", "SQUARE", 0) countTo = [3, 5, 7, 9] for i, n in enumerate(countTo): @@ -337,33 +342,25 @@ def testCoreStatus_Pack(mockGUI, mockRnd): ("New", { "key": statusKeys[0], "count": "3", - "red": "100", - "green": "100", - "blue": "100", + "color": "#646464", "shape": "SQUARE", }), ("Note", { "key": statusKeys[1], "count": "5", - "red": "200", - "green": "50", - "blue": "0", + "color": "#c83200", "shape": "CIRCLE", }), ("Draft", { "key": statusKeys[2], "count": "7", - "red": "200", - "green": "150", - "blue": "0", + "color": "#c89600", "shape": "SQUARE", }), ("Finished", { "key": statusKeys[3], "count": "9", - "red": "50", - "green": "200", - "blue": "0", + "color": "#32c800", "shape": "SQUARE", }), ] diff --git a/tests/test_dialogs/test_dlg_projectsettings.py b/tests/test_dialogs/test_dlg_projectsettings.py index edd0cebe..c20382d1 100644 --- a/tests/test_dialogs/test_dlg_projectsettings.py +++ b/tests/test_dialogs/test_dlg_projectsettings.py @@ -214,22 +214,22 @@ 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(120, 120, 120) + assert update[0][1].color.getRgb() == (108, 108, 108, 255) 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(143, 240, 164) + assert update[1][1].color.getRgb() == (163, 156, 52, 255) 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(249, 240, 107) + assert update[2][1].color.getRgb() == (41, 102, 41, 255) assert update[2][1].shape == nwStatusShape.STAR assert update[3][0] is None assert update[3][1].name == "Final" - assert update[3][1].color == QColor(20, 30, 40) + assert update[3][1].color.getRgb() == (20, 30, 40, 255) assert update[3][1].shape == nwStatusShape.CIRCLE # Move items, none selected -> no change @@ -289,22 +289,22 @@ 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(120, 120, 120) + assert update[0][1].color.getRgb() == (179, 90, 179, 255) 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(220, 138, 221) + assert update[1][1].color.getRgb() == (179, 90, 179, 255) 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(220, 138, 221) + assert update[2][1].color.getRgb() == (179, 90, 179, 255) assert update[2][1].shape == nwStatusShape.BLOCK_4 assert update[3][0] is None assert update[3][1].name == "Final" - assert update[3][1].color == QColor(20, 30, 40) + assert update[3][1].color.getRgb() == (20, 30, 40, 255) assert update[3][1].shape == nwStatusShape.TRIANGLE # Check Project @@ -354,10 +354,10 @@ def testDlgProjSettings_StatusImportExport(qtbot, monkeypatch, nwGUI, projPath, assert expFile.is_file() is True assert expFile.read_text().split() == [ - "STAR,#787878,New", - "TRIANGLE,#cdab8f,Note", - "CIRCLE_T,#8ff0a4,Draft", - "STAR,#f9f06b,Finished", + "STAR,#6c6c6c,New", + "TRIANGLE,#a62a2d,Note", + "CIRCLE_T,#a39c34,Draft", + "STAR,#296629,Finished", ] # Import Error diff --git a/tests/test_gui/test_gui_docviewerpanel.py b/tests/test_gui/test_gui_docviewerpanel.py index b0d02493..f51d9a81 100644 --- a/tests/test_gui/test_gui_docviewerpanel.py +++ b/tests/test_gui/test_gui_docviewerpanel.py @@ -224,7 +224,7 @@ def testGuiViewerPanel_Tags(qtbot, monkeypatch, caplog, nwGUI, projPath, mockRnd # Update Labels assert charTab.topLevelItem(0).text(charTab.C_IMPORT) == "New" - SHARED.project.data.itemImport.add(C.iNew, "Stuff", (100, 100, 100), "SQUARE", 0) + SHARED.project.data.itemImport.add(C.iNew, "Stuff", "#646464", "SQUARE", 0) viewPanel.updateStatusLabels("i") assert charTab.topLevelItem(0).text(charTab.C_IMPORT) == "Stuff"