Update and reorganise themes (#893)
* Drop the subfolders for GUI themes * Remove bundled font support * Add safe file read function * Allow loading themes from multiple locations * Clean up unused variables * Clean up icons class * Merge icon theme icons * Update icon theme class * Remove guiDark config setting * Fix tests * Fix handling of default theme * Update icon readmes * Add test for getGuiItem common function
This commit is contained in:
committed by
GitHub
parent
be3376272e
commit
15ec1496c5
@@ -1,9 +1,8 @@
|
||||
[Main]
|
||||
timestamp = 2021-09-10 00:23:50
|
||||
timestamp = 2021-09-15 14:39:52
|
||||
theme = default
|
||||
syntax = default_light
|
||||
icons = typicons_light
|
||||
guidark = False
|
||||
guifont =
|
||||
guifontsize = 11
|
||||
lastnotes = 0x0
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
[Main]
|
||||
timestamp = 2021-09-10 00:23:52
|
||||
timestamp = 2021-09-15 14:29:30
|
||||
theme = default
|
||||
syntax = default_light
|
||||
icons = typicons_light
|
||||
guidark = True
|
||||
guifont = Sans
|
||||
guifontsize = 12
|
||||
lastnotes = 0x0
|
||||
|
||||
@@ -29,12 +29,13 @@ from datetime import datetime
|
||||
from mock import causeOSError
|
||||
from tools import writeFile
|
||||
|
||||
from novelwriter.guimain import GuiMain
|
||||
from novelwriter.common import (
|
||||
checkString, checkInt, checkBool, checkHandle, isHandle, isTitleTag,
|
||||
isItemClass, isItemType, isItemLayout, hexToInt, formatInt,
|
||||
formatTimeStamp, formatTime, parseTimeStamp, splitVersionNumber,
|
||||
transferCase, fuzzyTime, numberToRoman, jsonEncode, makeFileNameSafe,
|
||||
sha256sum, NWConfigParser
|
||||
transferCase, fuzzyTime, numberToRoman, jsonEncode, readTextFile,
|
||||
makeFileNameSafe, sha256sum, getGuiItem, NWConfigParser
|
||||
)
|
||||
|
||||
|
||||
@@ -456,6 +457,24 @@ def testBaseCommon_JsonEncode():
|
||||
# END Test testBaseCommon_JsonEncode
|
||||
|
||||
|
||||
@pytest.mark.base
|
||||
def testBaseCommon_ReadTextFile(monkeypatch, fncDir, ipsumText):
|
||||
"""Test the readTextFile function.
|
||||
"""
|
||||
testText = "\n\n".join(ipsumText) + "\n"
|
||||
testFile = os.path.join(fncDir, "ipsum.txt")
|
||||
writeFile(testFile, testText)
|
||||
|
||||
assert readTextFile(os.path.join(fncDir, "not_a_file.txt")) == ""
|
||||
assert readTextFile(testFile) == testText
|
||||
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr("builtins.open", causeOSError)
|
||||
assert readTextFile(testFile) == ""
|
||||
|
||||
# END Test testBaseCommon_ReadTextFile
|
||||
|
||||
|
||||
@pytest.mark.base
|
||||
def testBaseCommon_MakeFileNameSafe():
|
||||
"""Test the makeFileNameSafe function.
|
||||
@@ -508,6 +527,16 @@ def testBaseCommon_Sha256Sum(monkeypatch, fncDir, ipsumText):
|
||||
# END Test testBaseCommon_Sha256Sum
|
||||
|
||||
|
||||
@pytest.mark.base
|
||||
def testBaseCommon_GetGuiItem(nwGUI):
|
||||
"""Check the GUI item function.
|
||||
"""
|
||||
assert getGuiItem("gibberish") is None
|
||||
assert isinstance(getGuiItem("GuiMain"), GuiMain)
|
||||
|
||||
# END Test testBaseCommon_GetGuiItem
|
||||
|
||||
|
||||
@pytest.mark.base
|
||||
def testBaseCommon_NWConfigParser(fncDir):
|
||||
"""Test the NWConfigParser subclass.
|
||||
|
||||
@@ -139,7 +139,7 @@ def testBaseConfig_Init(monkeypatch, tmpDir, fncDir, outDir, refDir, filesDir):
|
||||
assert os.path.isfile(confFile)
|
||||
|
||||
copyfile(confFile, testFile)
|
||||
assert cmpFiles(testFile, compFile, [2, 9, 10])
|
||||
assert cmpFiles(testFile, compFile, ignoreStart=("timestamp", "lastnotes", "guilang"))
|
||||
|
||||
# Load and save with OSError
|
||||
with monkeypatch.context() as mp:
|
||||
@@ -255,7 +255,7 @@ def testBaseConfig_Init(monkeypatch, tmpDir, fncDir, outDir, refDir, filesDir):
|
||||
assert theList == [("en_GB", "British English"), ("fr", "Français")]
|
||||
|
||||
copyfile(confFile, testFile)
|
||||
assert cmpFiles(testFile, compFile, [2, 9, 10])
|
||||
assert cmpFiles(testFile, compFile, ignoreStart=("timestamp", "lastnotes", "guilang"))
|
||||
|
||||
# END Test testBaseConfig_Init
|
||||
|
||||
@@ -539,7 +539,7 @@ def testBaseConfig_SettersGetters(tmpConf, tmpDir, outDir, refDir):
|
||||
assert tmpConf.confChanged is False
|
||||
|
||||
copyfile(confFile, testFile)
|
||||
assert cmpFiles(testFile, compFile, [2, 9, 10])
|
||||
assert cmpFiles(testFile, compFile, ignoreStart=("timestamp", "lastnotes", "guilang"))
|
||||
|
||||
# END Test testBaseConfig_SettersGetters
|
||||
|
||||
|
||||
@@ -84,11 +84,6 @@ def testDlgPreferences_Main(qtbot, monkeypatch, fncDir, outDir, refDir):
|
||||
tabGeneral = nwPrefs.tabGeneral
|
||||
nwPrefs._tabBox.setCurrentWidget(tabGeneral)
|
||||
|
||||
qtbot.wait(keyDelay)
|
||||
assert not tabGeneral.guiDark.isChecked()
|
||||
qtbot.mouseClick(tabGeneral.guiDark, Qt.LeftButton)
|
||||
assert tabGeneral.guiDark.isChecked()
|
||||
|
||||
qtbot.wait(keyDelay)
|
||||
assert tabGeneral.showFullPath.isChecked()
|
||||
qtbot.mouseClick(tabGeneral.showFullPath, Qt.LeftButton)
|
||||
@@ -249,8 +244,12 @@ def testDlgPreferences_Main(qtbot, monkeypatch, fncDir, outDir, refDir):
|
||||
testFile = os.path.join(outDir, "guiPreferences_novelwriter.conf")
|
||||
compFile = os.path.join(refDir, "guiPreferences_novelwriter.conf")
|
||||
copyfile(projFile, testFile)
|
||||
ignoreLines = [2, 7, 9, 10, 15, 16, 17, 18, 19, 20, 21, 22, 23, 32, 33]
|
||||
assert cmpFiles(testFile, compFile, ignoreLines)
|
||||
ignTuple = (
|
||||
"timestamp", "guifont", "lastnotes", "guilang", "geometry",
|
||||
"preferences", "treecols", "novelcols", "projcols", "mainpane",
|
||||
"docpane", "viewpane", "outlinepane", "textfont", "textsize"
|
||||
)
|
||||
assert cmpFiles(testFile, compFile, ignoreStart=ignTuple)
|
||||
|
||||
# Clean up
|
||||
novelwriter.CONFIG = origConf
|
||||
|
||||
@@ -23,7 +23,7 @@ import pytest
|
||||
import novelwriter
|
||||
|
||||
from PyQt5.QtGui import QColor, QPixmap, QIcon
|
||||
from PyQt5.QtWidgets import QStyle, QMessageBox
|
||||
from PyQt5.QtWidgets import QMessageBox
|
||||
|
||||
keyDelay = 2
|
||||
typeDelay = 1
|
||||
@@ -50,7 +50,6 @@ def testGuiTheme_Main(qtbot, monkeypatch, nwMinimal, tmpDir):
|
||||
novelwriter.CONFIG.guiTheme = "default_dark"
|
||||
novelwriter.CONFIG.guiSyntax = "tomorrow_night_eighties"
|
||||
novelwriter.CONFIG.guiIcons = "typicons_colour_dark"
|
||||
novelwriter.CONFIG.guiDark = True
|
||||
novelwriter.CONFIG.guiFont = "Cantarell"
|
||||
novelwriter.CONFIG.guiFontSize = 11
|
||||
novelwriter.CONFIG.confChanged = True
|
||||
@@ -73,9 +72,8 @@ def testGuiTheme_Main(qtbot, monkeypatch, nwMinimal, tmpDir):
|
||||
assert novelwriter.CONFIG.guiTheme == "default_dark"
|
||||
assert novelwriter.CONFIG.guiSyntax == "tomorrow_night_eighties"
|
||||
assert novelwriter.CONFIG.guiIcons == "typicons_dark"
|
||||
assert novelwriter.CONFIG.guiDark is True
|
||||
assert novelwriter.CONFIG.guiFont == "Cantarell"
|
||||
assert novelwriter.CONFIG.guiFontSize == 11
|
||||
assert novelwriter.CONFIG.guiFont != ""
|
||||
assert novelwriter.CONFIG.guiFontSize > 0
|
||||
|
||||
# Check GUI Colours
|
||||
thePalette = nwGUI.palette()
|
||||
@@ -119,9 +117,8 @@ def testGuiTheme_Main(qtbot, monkeypatch, nwMinimal, tmpDir):
|
||||
# Test Icon class
|
||||
theIcons = nwGUI.theTheme.theIcons
|
||||
novelwriter.CONFIG.guiIcons = "invalid"
|
||||
assert not theIcons.updateTheme()
|
||||
novelwriter.CONFIG.guiIcons = "typicons_dark"
|
||||
assert theIcons.updateTheme()
|
||||
assert theIcons.updateTheme() is True
|
||||
assert novelwriter.CONFIG.guiIcons == "typicons_light"
|
||||
|
||||
# Ask for a non-existent key
|
||||
anImg = theIcons.loadDecoration("nonsense", 20, 20)
|
||||
@@ -168,17 +165,8 @@ def testGuiTheme_Main(qtbot, monkeypatch, nwMinimal, tmpDir):
|
||||
assert isinstance(anIcon, QIcon)
|
||||
assert not anIcon.isNull()
|
||||
|
||||
# Add test icons and test alternative load paths
|
||||
theIcons.ICON_MAP["testicon1"] = (QStyle.SP_DriveHDIcon, None)
|
||||
anIcon = theIcons.getIcon("testicon1")
|
||||
assert isinstance(anIcon, QIcon)
|
||||
assert not anIcon.isNull()
|
||||
|
||||
theIcons.ICON_MAP["testicon2"] = (None, "folder")
|
||||
anIcon = theIcons.getIcon("testicon2")
|
||||
assert isinstance(anIcon, QIcon)
|
||||
|
||||
theIcons.ICON_MAP["testicon3"] = (None, None)
|
||||
# Check return empty icon if file not found
|
||||
theIcons.ICON_KEYS.add("testicon3")
|
||||
anIcon = theIcons.getIcon("testicon3")
|
||||
assert isinstance(anIcon, QIcon)
|
||||
assert anIcon.isNull()
|
||||
|
||||
+6
-1
@@ -25,7 +25,7 @@ import shutil
|
||||
from PyQt5.QtWidgets import qApp
|
||||
|
||||
|
||||
def cmpFiles(fileOne, fileTwo, ignoreLines=None):
|
||||
def cmpFiles(fileOne, fileTwo, ignoreLines=None, ignoreStart=None):
|
||||
"""Compare two files, but optionally ignore lines given by a list.
|
||||
"""
|
||||
if ignoreLines is None:
|
||||
@@ -59,6 +59,11 @@ def cmpFiles(fileOne, fileTwo, ignoreLines=None):
|
||||
print("Ignoring line %d" % (n+1))
|
||||
continue
|
||||
|
||||
if ignoreStart is not None:
|
||||
if lnOne.startswith(ignoreStart):
|
||||
print("Ignoring line %d" % (n+1))
|
||||
continue
|
||||
|
||||
if lnOne != lnTwo:
|
||||
print("Diff on line %d:" % (n+1))
|
||||
print(" << '%s'" % lnOne)
|
||||
|
||||
Reference in New Issue
Block a user