Update theme colour processing and fix current tests
This commit is contained in:
@@ -34,7 +34,7 @@ from PyQt6.QtWidgets import QInputDialog, QMessageBox
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.constants import nwFiles
|
||||
from novelwriter.dialogs.editlabel import GuiEditLabel
|
||||
from novelwriter.enum import nwDocAction, nwDocMode, nwFocus, nwItemType, nwView
|
||||
from novelwriter.enum import nwDocAction, nwDocMode, nwFocus, nwItemType, nwTheme, nwView
|
||||
from novelwriter.gui.doceditor import GuiDocEditor
|
||||
from novelwriter.gui.noveltree import GuiNovelView
|
||||
from novelwriter.gui.outline import GuiOutlineView
|
||||
@@ -180,10 +180,11 @@ def testGuiMain_ProjectTreeItems(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
||||
def testGuiMain_UpdateTheme(qtbot, nwGUI):
|
||||
"""Test updating the theme in the GUI."""
|
||||
mainTheme = SHARED.theme
|
||||
CONFIG.guiTheme = "default_dark"
|
||||
CONFIG.guiSyntax = "default_dark"
|
||||
CONFIG.themeMode = nwTheme.DARK
|
||||
CONFIG.darkTheme = "default_dark"
|
||||
CONFIG.lightTheme = "default_light"
|
||||
mainTheme.loadTheme()
|
||||
mainTheme.loadSyntax()
|
||||
|
||||
nwGUI._processConfigChanges(False, True, False, False)
|
||||
nwGUI._processConfigChanges(True, True, True, True)
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ from __future__ import annotations
|
||||
|
||||
import sys
|
||||
|
||||
from configparser import ConfigParser
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
@@ -29,8 +30,7 @@ import pytest
|
||||
from PyQt6.QtGui import QColor, QIcon, QPalette, QPixmap
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.common import NWConfigParser
|
||||
from novelwriter.config import DEF_GUI
|
||||
from novelwriter.config import DEF_GUI_LIGHT
|
||||
from novelwriter.constants import nwLabels
|
||||
from novelwriter.enum import nwItemClass, nwItemLayout, nwItemType
|
||||
from novelwriter.gui.theme import _listConf
|
||||
@@ -39,17 +39,51 @@ from tests.mocked import causeOSError
|
||||
from tests.tools import writeFile
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def testGuiTheme_ParseColor(qtbot, nwGUI):
|
||||
"""Test the colour parsing."""
|
||||
theme = SHARED.theme
|
||||
|
||||
# Pre-Populate
|
||||
theme._qColors["red"] = QColor(255, 0, 0)
|
||||
theme._qColors["green"] = QColor(0, 255, 0)
|
||||
theme._qColors["blue"] = QColor(0, 0, 255)
|
||||
|
||||
# By Name
|
||||
assert theme.parseColor("red").getRgb() == (255, 0, 0, 255)
|
||||
assert theme.parseColor("green").getRgb() == (0, 255, 0, 255)
|
||||
assert theme.parseColor("blue").getRgb() == (0, 0, 255, 255)
|
||||
assert theme.parseColor("bob").getRgb() == (0, 0, 0, 255)
|
||||
|
||||
# CSS Format
|
||||
assert theme.parseColor("#ff0000").getRgb() == (255, 0, 0, 255)
|
||||
assert theme.parseColor("#ff00007f").getRgb() == (255, 0, 0, 127)
|
||||
assert theme.parseColor("#ff00").getRgb() == (0, 0, 0, 255) # Too short -> ignored
|
||||
assert theme.parseColor("#ff00007f15").getRgb() == (255, 0, 0, 127) # Too long -> truncated
|
||||
|
||||
# Name + Alpha
|
||||
assert theme.parseColor("red, 255").getRgb() == (255, 0, 0, 255)
|
||||
assert theme.parseColor("red, 127").getRgb() == (255, 0, 0, 127)
|
||||
assert theme.parseColor("red, 512").getRgb() == (255, 0, 0, 255) # Value truncated
|
||||
|
||||
# Values
|
||||
assert theme.parseColor("255, 0, 0").getRgb() == (255, 0, 0, 255)
|
||||
assert theme.parseColor("255, 0, 0, 255").getRgb() == (255, 0, 0, 255)
|
||||
assert theme.parseColor("255, 0, 0, 127").getRgb() == (255, 0, 0, 127)
|
||||
assert theme.parseColor("255, 0, 0, 127, 42").getRgb() == (255, 0, 0, 127) # Truncated
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def testGuiTheme_Main(qtbot, nwGUI, tstPaths):
|
||||
"""Test the theme class init."""
|
||||
mainTheme = SHARED.theme
|
||||
theme = SHARED.theme
|
||||
|
||||
# Methods
|
||||
# =======
|
||||
|
||||
mSize = mainTheme.getTextWidth("m")
|
||||
mSize = theme.getTextWidth("m")
|
||||
assert mSize > 0
|
||||
assert mainTheme.getTextWidth("m", mainTheme.guiFont) == mSize
|
||||
assert theme.getTextWidth("m", theme.guiFont) == mSize
|
||||
|
||||
# Scan for Themes
|
||||
# ===============
|
||||
@@ -70,7 +104,7 @@ def testGuiTheme_Main(qtbot, nwGUI, tstPaths):
|
||||
# Parse Colours
|
||||
# =============
|
||||
|
||||
parser = NWConfigParser()
|
||||
parser = ConfigParser()
|
||||
parser["Palette"] = {
|
||||
"colour1": "100, 150, 200", # Valid
|
||||
"colour2": "100, 150, 200, 250", # With alpha
|
||||
@@ -81,38 +115,39 @@ def testGuiTheme_Main(qtbot, nwGUI, tstPaths):
|
||||
}
|
||||
|
||||
# Test the parser for several valid and invalid values
|
||||
assert mainTheme._parseColor(parser, "Palette", "colour1").getRgb() == (100, 150, 200, 255)
|
||||
assert mainTheme._parseColor(parser, "Palette", "colour2").getRgb() == (100, 150, 200, 250)
|
||||
assert mainTheme._parseColor(parser, "Palette", "colour3").getRgb() == (100, 150, 200, 250)
|
||||
assert mainTheme._parseColor(parser, "Palette", "colour4").getRgb() == (250, 250, 0, 255)
|
||||
assert mainTheme._parseColor(parser, "Palette", "colour5").getRgb() == (0, 0, 0, 0)
|
||||
assert mainTheme._parseColor(parser, "Palette", "colour6").getRgb() == (0, 127, 255, 255)
|
||||
assert theme._readColor(parser, "Palette", "colour1").getRgb() == (100, 150, 200, 255)
|
||||
assert theme._readColor(parser, "Palette", "colour2").getRgb() == (100, 150, 200, 250)
|
||||
assert theme._readColor(parser, "Palette", "colour3").getRgb() == (100, 150, 200, 250)
|
||||
assert theme._readColor(parser, "Palette", "colour4").getRgb() == (0, 0, 0, 250)
|
||||
assert theme._readColor(parser, "Palette", "colour5").getRgb() == (0, 0, 0, 0)
|
||||
assert theme._readColor(parser, "Palette", "colour6").getRgb() == (0, 127, 255, 255)
|
||||
|
||||
# The palette should load with the parsed values
|
||||
mainTheme._setPalette(parser, "Palette", "colour1", QPalette.ColorRole.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (100, 150, 200, 255)
|
||||
mainTheme._setPalette(parser, "Palette", "colour2", QPalette.ColorRole.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (100, 150, 200, 250)
|
||||
mainTheme._setPalette(parser, "Palette", "colour3", QPalette.ColorRole.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (100, 150, 200, 250)
|
||||
mainTheme._setPalette(parser, "Palette", "colour4", QPalette.ColorRole.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (250, 250, 0, 255)
|
||||
mainTheme._setPalette(parser, "Palette", "colour5", QPalette.ColorRole.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (0, 0, 0, 0)
|
||||
mainTheme._setPalette(parser, "Palette", "colour6", QPalette.ColorRole.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (0, 127, 255, 255)
|
||||
theme._setPalette(parser, "Palette", "colour1", QPalette.ColorRole.Window)
|
||||
assert theme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (100, 150, 200, 255)
|
||||
theme._setPalette(parser, "Palette", "colour2", QPalette.ColorRole.Window)
|
||||
assert theme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (100, 150, 200, 250)
|
||||
theme._setPalette(parser, "Palette", "colour3", QPalette.ColorRole.Window)
|
||||
assert theme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (100, 150, 200, 250)
|
||||
theme._setPalette(parser, "Palette", "colour4", QPalette.ColorRole.Window)
|
||||
assert theme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (0, 0, 0, 250)
|
||||
theme._setPalette(parser, "Palette", "colour5", QPalette.ColorRole.Window)
|
||||
assert theme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (0, 0, 0, 0)
|
||||
theme._setPalette(parser, "Palette", "colour6", QPalette.ColorRole.Window)
|
||||
assert theme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (0, 127, 255, 255)
|
||||
|
||||
# Non-existing value should return default colour
|
||||
mainTheme._setPalette(parser, "Palette", "stuff", QPalette.ColorRole.Window)
|
||||
assert mainTheme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (0, 0, 0, 255)
|
||||
theme._setPalette(parser, "Palette", "stuff", QPalette.ColorRole.Window)
|
||||
assert theme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (0, 0, 0, 255)
|
||||
|
||||
# qtbot.stop()
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
@pytest.mark.skip
|
||||
def testGuiTheme_Theme(qtbot, monkeypatch, nwGUI, tstPaths):
|
||||
"""Test the theme part of the class."""
|
||||
mainTheme = SHARED.theme
|
||||
theme = SHARED.theme
|
||||
|
||||
# List Themes
|
||||
# ===========
|
||||
@@ -120,45 +155,46 @@ def testGuiTheme_Theme(qtbot, monkeypatch, nwGUI, tstPaths):
|
||||
# Block the reading of the files
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr("builtins.open", causeOSError)
|
||||
assert mainTheme.listThemes() == []
|
||||
theme._themeList = []
|
||||
assert theme.listThemes() == []
|
||||
|
||||
# Load the theme info, default themes first
|
||||
themesList = mainTheme.listThemes()
|
||||
themesList = theme.listThemes()
|
||||
assert themesList[0] == ("default_dark", "Default Dark Theme")
|
||||
assert themesList[1] == ("default_light", "Default Light Theme")
|
||||
assert themesList[2] == ("cyberpunk_night", "Cyberpunk Night")
|
||||
assert themesList[3] == ("dracula", "Dracula")
|
||||
|
||||
# A second call should returned the cached list
|
||||
assert mainTheme.listThemes() == mainTheme._themeList
|
||||
assert theme.listThemes() == theme._themeList
|
||||
|
||||
# Check handling of broken theme settings
|
||||
CONFIG.guiTheme = "not_a_theme"
|
||||
availThemes = mainTheme._availThemes
|
||||
mainTheme._availThemes = {}
|
||||
assert mainTheme.loadTheme() is False
|
||||
mainTheme._availThemes = availThemes
|
||||
availThemes = theme._availThemes
|
||||
theme._availThemes = {}
|
||||
assert theme.loadTheme() is False
|
||||
theme._availThemes = availThemes
|
||||
|
||||
# Check handling of unreadable file
|
||||
CONFIG.guiTheme = DEF_GUI
|
||||
CONFIG.guiTheme = DEF_GUI_LIGHT
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr("builtins.open", causeOSError)
|
||||
assert mainTheme.loadTheme() is False
|
||||
assert theme.loadTheme() is False
|
||||
|
||||
# Load Default Theme
|
||||
# ==================
|
||||
|
||||
if sys.platform != "win32":
|
||||
# Set a mock colour for the window background
|
||||
mainTheme._guiPalette.color(QPalette.ColorRole.Window).setRgb(0, 0, 0, 0)
|
||||
theme._guiPalette.color(QPalette.ColorRole.Window).setRgb(0, 0, 0, 0)
|
||||
|
||||
# Load the default theme
|
||||
CONFIG.guiTheme = DEF_GUI
|
||||
assert mainTheme.loadTheme() is True
|
||||
CONFIG.guiTheme = DEF_GUI_LIGHT
|
||||
assert theme.loadTheme() is True
|
||||
|
||||
# This should load a standard palette
|
||||
wCol = QPalette().color(QPalette.ColorRole.Window).getRgb()
|
||||
assert mainTheme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == wCol
|
||||
assert theme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == wCol
|
||||
|
||||
# Mock Dark Theme
|
||||
# ===============
|
||||
@@ -172,32 +208,32 @@ def testGuiTheme_Theme(qtbot, monkeypatch, nwGUI, tstPaths):
|
||||
"window = 0, 0, 0\n"
|
||||
"text = 255, 255, 255\n"
|
||||
)
|
||||
mainTheme._availThemes["test"] = mockTheme
|
||||
theme._availThemes["test"] = mockTheme
|
||||
|
||||
CONFIG.guiTheme = "test"
|
||||
assert mainTheme.loadTheme() is True
|
||||
assert mainTheme._guiPalette.window().color().getRgb() == (0, 0, 0, 255)
|
||||
assert mainTheme._guiPalette.text().color().getRgb() == (255, 255, 255, 255)
|
||||
assert mainTheme._guiPalette.light().color().getRgb() == (57, 57, 57, 255)
|
||||
assert mainTheme.isDarkTheme is True
|
||||
assert theme.loadTheme() is True
|
||||
assert theme._guiPalette.window().color().getRgb() == (0, 0, 0, 255)
|
||||
assert theme._guiPalette.text().color().getRgb() == (255, 255, 255, 255)
|
||||
assert theme._guiPalette.light().color().getRgb() == (57, 57, 57, 255)
|
||||
assert theme.isDarkTheme is True
|
||||
|
||||
# Load Default Light Theme
|
||||
# ========================
|
||||
|
||||
CONFIG.guiTheme = "default_light"
|
||||
assert mainTheme.loadTheme() is True
|
||||
assert theme.loadTheme() is True
|
||||
|
||||
# Check a few values
|
||||
assert mainTheme._guiPalette.color(
|
||||
assert theme._guiPalette.color(
|
||||
QPalette.ColorRole.Window
|
||||
).getRgb() == (239, 239, 239, 255)
|
||||
assert mainTheme._guiPalette.color(
|
||||
assert theme._guiPalette.color(
|
||||
QPalette.ColorRole.WindowText
|
||||
).getRgb() == (0, 0, 0, 255)
|
||||
assert mainTheme._guiPalette.color(
|
||||
assert theme._guiPalette.color(
|
||||
QPalette.ColorRole.Base
|
||||
).getRgb() == (255, 255, 255, 255)
|
||||
assert mainTheme._guiPalette.color(
|
||||
assert theme._guiPalette.color(
|
||||
QPalette.ColorRole.AlternateBase
|
||||
).getRgb() == (224, 224, 224, 255)
|
||||
|
||||
@@ -205,21 +241,22 @@ def testGuiTheme_Theme(qtbot, monkeypatch, nwGUI, tstPaths):
|
||||
# =======================
|
||||
|
||||
CONFIG.guiTheme = "default_dark"
|
||||
assert mainTheme.loadTheme() is True
|
||||
assert theme.loadTheme() is True
|
||||
|
||||
# Check a few values
|
||||
assert mainTheme._guiPalette.color(
|
||||
assert theme._guiPalette.color(
|
||||
QPalette.ColorRole.Window).getRgb() == (54, 54, 54, 255)
|
||||
assert mainTheme._guiPalette.color(
|
||||
assert theme._guiPalette.color(
|
||||
QPalette.ColorRole.WindowText).getRgb() == (204, 204, 204, 255)
|
||||
assert mainTheme._guiPalette.color(
|
||||
assert theme._guiPalette.color(
|
||||
QPalette.ColorRole.Base).getRgb() == (62, 62, 62, 255)
|
||||
assert mainTheme._guiPalette.color(
|
||||
assert theme._guiPalette.color(
|
||||
QPalette.ColorRole.AlternateBase).getRgb() == (78, 78, 78, 255)
|
||||
|
||||
# qtbot.stop()
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
@pytest.mark.gui
|
||||
def testGuiTheme_Syntax(qtbot, monkeypatch, nwGUI):
|
||||
"""Test the syntax part of the class."""
|
||||
@@ -283,6 +320,7 @@ def testGuiTheme_Syntax(qtbot, monkeypatch, nwGUI):
|
||||
# qtbot.stop()
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
@pytest.mark.gui
|
||||
def testGuiTheme_IconThemes(qtbot, caplog, monkeypatch, nwGUI, tstPaths):
|
||||
"""Test the icon cache class."""
|
||||
|
||||
Reference in New Issue
Block a user