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:
Veronica Berglyd Olsen
2021-09-19 14:09:20 +02:00
committed by GitHub
parent be3376272e
commit 15ec1496c5
201 changed files with 482 additions and 2043 deletions
+1 -2
View File
@@ -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
+31 -2
View File
@@ -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.
+3 -3
View File
@@ -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
+6 -7
View File
@@ -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
+7 -19
View File
@@ -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
View File
@@ -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)