From 82188d156bb6e7bf57e4e83a6c97f8c8bf2aa2b6 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Tue, 3 Jun 2025 12:02:38 +0200 Subject: [PATCH] Change the name and alpha format of colour themes --- novelwriter/assets/themes/default_dark.conf | 4 +- novelwriter/assets/themes/default_light.conf | 2 +- novelwriter/assets/themes/light_owl.conf | 4 +- novelwriter/assets/themes/night_owl.conf | 4 +- novelwriter/assets/themes/tango_dark.conf | 6 +- novelwriter/assets/themes/tango_light.conf | 10 +-- novelwriter/assets/themes/tomorrow.conf | 4 +- novelwriter/assets/themes/tomorrow_night.conf | 4 +- .../assets/themes/tomorrow_night_blue.conf | 4 +- .../assets/themes/tomorrow_night_bright.conf | 4 +- .../themes/tomorrow_night_eighties.conf | 4 +- novelwriter/gui/sidebar.py | 12 ++-- novelwriter/gui/theme.py | 36 +++++----- tests/test_gui/test_gui_theme.py | 72 +++++++++---------- 14 files changed, 84 insertions(+), 86 deletions(-) diff --git a/novelwriter/assets/themes/default_dark.conf b/novelwriter/assets/themes/default_dark.conf index 35acdb4c..71943bd8 100644 --- a/novelwriter/assets/themes/default_dark.conf +++ b/novelwriter/assets/themes/default_dark.conf @@ -54,7 +54,7 @@ background = #363636 text = default link = blue headertext = green -headertag = green, 160 +headertag = green:160 emphasis = orange dialog = blue altdialog = blue @@ -69,4 +69,4 @@ spellcheckline = red errorline = green replacetag = green modifier = green -texthighlight = yellow, 72 +texthighlight = yellow:72 diff --git a/novelwriter/assets/themes/default_light.conf b/novelwriter/assets/themes/default_light.conf index 0c309a3c..a67759dc 100644 --- a/novelwriter/assets/themes/default_light.conf +++ b/novelwriter/assets/themes/default_light.conf @@ -54,7 +54,7 @@ background = #ffffff text = #000000 link = blue headertext = green -headertag = green, 160 +headertag = green:160 emphasis = orange dialog = blue altdialog = blue diff --git a/novelwriter/assets/themes/light_owl.conf b/novelwriter/assets/themes/light_owl.conf index f72b8d70..3544b6cd 100644 --- a/novelwriter/assets/themes/light_owl.conf +++ b/novelwriter/assets/themes/light_owl.conf @@ -73,7 +73,7 @@ background = #fbfbfb text = default link = blue headertext = blue -headertag = blue, 160 +headertag = blue:160 emphasis = orange dialog = green altdialog = yellow @@ -88,4 +88,4 @@ spellcheckline = red errorline = green replacetag = aqua modifier = green -texthighlight = yellow, 96 +texthighlight = yellow:96 diff --git a/novelwriter/assets/themes/night_owl.conf b/novelwriter/assets/themes/night_owl.conf index 0d176c45..36ec3432 100644 --- a/novelwriter/assets/themes/night_owl.conf +++ b/novelwriter/assets/themes/night_owl.conf @@ -73,7 +73,7 @@ background = #011627 text = default link = blue headertext = blue -headertag = blue, 160 +headertag = blue:160 emphasis = orange dialog = green altdialog = yellow @@ -88,4 +88,4 @@ spellcheckline = red errorline = green replacetag = aqua modifier = green -texthighlight = yellow, 96 +texthighlight = yellow:96 diff --git a/novelwriter/assets/themes/tango_dark.conf b/novelwriter/assets/themes/tango_dark.conf index ca0ba841..9c4dc59e 100644 --- a/novelwriter/assets/themes/tango_dark.conf +++ b/novelwriter/assets/themes/tango_dark.conf @@ -63,7 +63,7 @@ background = #2e3436 text = default link = blue headertext = blue -headertag = blue, 160 +headertag = blue:160 emphasis = orange dialog = green altdialog = yellow @@ -76,6 +76,6 @@ value = red optional = blue spellcheckline = red errorline = green -replacetag = cyan +replacetag = aqua modifier = blue -texthighlight = yellow, 96 +texthighlight = yellow:96 diff --git a/novelwriter/assets/themes/tango_light.conf b/novelwriter/assets/themes/tango_light.conf index 174b0571..3c66d1e9 100644 --- a/novelwriter/assets/themes/tango_light.conf +++ b/novelwriter/assets/themes/tango_light.conf @@ -1,6 +1,6 @@ [Main] -name = Tango Light -mode = light +name = Tango Light +mode = light author = Veronica Berglyd Olsen (adaptation) ## @@ -63,7 +63,7 @@ background = #eeeeec text = default link = blue headertext = blue -headertag = blue, 160 +headertag = blue:160 emphasis = orange dialog = green altdialog = yellow @@ -76,6 +76,6 @@ value = red optional = blue spellcheckline = red errorline = green -replacetag = cyan +replacetag = aqua modifier = blue -texthighlight = yellow, 96 +texthighlight = yellow:96 diff --git a/novelwriter/assets/themes/tomorrow.conf b/novelwriter/assets/themes/tomorrow.conf index 2b734209..f8b9d5df 100644 --- a/novelwriter/assets/themes/tomorrow.conf +++ b/novelwriter/assets/themes/tomorrow.conf @@ -73,7 +73,7 @@ background = #ffffff text = #4d4d4c link = blue headertext = blue -headertag = blue, 160 +headertag = blue:160 emphasis = orange dialog = green altdialog = yellow @@ -88,4 +88,4 @@ spellcheckline = red errorline = green replacetag = aqua modifier = orange -texthighlight = yellow, 96 +texthighlight = yellow:96 diff --git a/novelwriter/assets/themes/tomorrow_night.conf b/novelwriter/assets/themes/tomorrow_night.conf index 27abd454..d0e91fbd 100644 --- a/novelwriter/assets/themes/tomorrow_night.conf +++ b/novelwriter/assets/themes/tomorrow_night.conf @@ -73,7 +73,7 @@ background = #1d1f21 text = default link = blue headertext = blue -headertag = blue, 160 +headertag = blue:160 emphasis = orange dialog = green altdialog = yellow @@ -88,4 +88,4 @@ spellcheckline = red errorline = green replacetag = aqua modifier = orange -texthighlight = yellow, 96 +texthighlight = yellow:96 diff --git a/novelwriter/assets/themes/tomorrow_night_blue.conf b/novelwriter/assets/themes/tomorrow_night_blue.conf index 93b6592e..79fa3ea4 100644 --- a/novelwriter/assets/themes/tomorrow_night_blue.conf +++ b/novelwriter/assets/themes/tomorrow_night_blue.conf @@ -73,7 +73,7 @@ background = #002451 text = default link = blue headertext = blue -headertag = blue, 160 +headertag = blue:160 emphasis = orange dialog = green altdialog = yellow @@ -88,4 +88,4 @@ spellcheckline = red errorline = green replacetag = aqua modifier = orange -texthighlight = yellow, 96 +texthighlight = yellow:96 diff --git a/novelwriter/assets/themes/tomorrow_night_bright.conf b/novelwriter/assets/themes/tomorrow_night_bright.conf index de76e694..3c2ad22d 100644 --- a/novelwriter/assets/themes/tomorrow_night_bright.conf +++ b/novelwriter/assets/themes/tomorrow_night_bright.conf @@ -73,7 +73,7 @@ background = #000000 text = default link = blue headertext = blue -headertag = blue, 160 +headertag = blue:160 emphasis = orange dialog = green altdialog = yellow @@ -88,4 +88,4 @@ spellcheckline = red errorline = green replacetag = aqua modifier = orange -texthighlight = yellow, 96 +texthighlight = yellow:96 diff --git a/novelwriter/assets/themes/tomorrow_night_eighties.conf b/novelwriter/assets/themes/tomorrow_night_eighties.conf index e3e8bbec..8f969073 100644 --- a/novelwriter/assets/themes/tomorrow_night_eighties.conf +++ b/novelwriter/assets/themes/tomorrow_night_eighties.conf @@ -73,7 +73,7 @@ background = #2d2d2d text = default link = blue headertext = blue -headertag = blue, 160 +headertag = blue:160 emphasis = orange dialog = green altdialog = yellow @@ -88,4 +88,4 @@ spellcheckline = red errorline = green replacetag = aqua modifier = orange -texthighlight = yellow, 96 +texthighlight = yellow:96 diff --git a/novelwriter/gui/sidebar.py b/novelwriter/gui/sidebar.py index a4dd3c9c..e0ccb9e5 100644 --- a/novelwriter/gui/sidebar.py +++ b/novelwriter/gui/sidebar.py @@ -82,10 +82,6 @@ class GuiSideBar(QWidget): self.tbTheme.setToolTip(self.tr("Switch Colour Theme")) self.tbTheme.clicked.connect(self._cycleColurTheme) - self.tbBuild = NIconToolButton(self, iSz) - self.tbBuild.setToolTip("{0} [F5]".format(self.tr("Build Manuscript"))) - self.tbBuild.clicked.connect(self.mainGui.showBuildManuscriptDialog) - self.tbDetails = NIconToolButton(self, iSz) self.tbDetails.setToolTip("{0} [Shift+F6]".format(self.tr("Novel Details"))) self.tbDetails.clicked.connect(self.mainGui.showNovelDetailsDialog) @@ -94,6 +90,10 @@ class GuiSideBar(QWidget): self.tbStats.setToolTip("{0} [F6]".format(self.tr("Writing Statistics"))) self.tbStats.clicked.connect(self.mainGui.showWritingStatsDialog) + self.tbBuild = NIconToolButton(self, iSz) + self.tbBuild.setToolTip("{0} [F5]".format(self.tr("Build Manuscript"))) + self.tbBuild.clicked.connect(self.mainGui.showBuildManuscriptDialog) + # Settings Menu self.tbSettings = NIconToolButton(self, iSz) self.tbSettings.setToolTip(self.tr("Settings")) @@ -114,9 +114,9 @@ class GuiSideBar(QWidget): self.outerBox.addWidget(self.tbOutline) self.outerBox.addWidget(self.tbBuild) self.outerBox.addStretch(1) - self.outerBox.addWidget(self.tbTheme) self.outerBox.addWidget(self.tbDetails) self.outerBox.addWidget(self.tbStats) + self.outerBox.addWidget(self.tbTheme) self.outerBox.addWidget(self.tbSettings) self.outerBox.setContentsMargins(0, 0, 0, 0) self.outerBox.setSpacing(6) @@ -137,9 +137,9 @@ class GuiSideBar(QWidget): self.tbSearch.setStyleSheet(buttonStyle) self.tbOutline.setStyleSheet(buttonStyle) self.tbBuild.setStyleSheet(buttonStyle) - self.tbTheme.setStyleSheet(buttonStyle) self.tbDetails.setStyleSheet(buttonStyle) self.tbStats.setStyleSheet(buttonStyle) + self.tbTheme.setStyleSheet(buttonStyle) self.tbSettings.setStyleSheet(buttonStyle) self.tbProject.setThemeIcon("sb_project") diff --git a/novelwriter/gui/theme.py b/novelwriter/gui/theme.py index bcdb1108..236bebe7 100644 --- a/novelwriter/gui/theme.py +++ b/novelwriter/gui/theme.py @@ -229,27 +229,25 @@ class GuiTheme: if value in self._qColors: # Named colour return self._qColors[value] - elif value.startswith("#"): - if len(value) >= 9: - # Convert from #RRGGBBAA to #AARRGGBB - return QColor.fromString(f"#{value[7:9]}{value[1:7]}") - else: - # Assume #RRGGBB - return QColor.fromString(value[:7]) + elif value.startswith("#") and len(value) == 7: + # Assume #RRGGBB + return QColor.fromString(value) + elif value.startswith("#") and len(value) == 9: + # Assume #RRGGBBAA and convert to #AARRGGBB + return QColor.fromString(f"#{value[7:9]}{value[1:7]}") + elif ":" in value: + # Colour name and alpha + name, _, alpha = value.partition(":") + color = QColor(self._qColors.get(name.strip(), default)) + color.setAlpha(checkInt(alpha, 255)) + return color elif "," in value: + # Integer red, green, blue, alpha data = value.split(",") - entries = len(data) - if entries == 2: - # Assume name, alpha - color = QColor(self._qColors.get(data[0].strip(), default)) - color.setAlpha(checkInt(data[1], 255)) - return color - else: - # Assume red, green, blue, alpha - result = [0, 0, 0, 255] - for i in range(min(entries, 4)): - result[i] = checkInt(data[i].strip(), result[i]) - return QColor(*result) + result = [0, 0, 0, 255] + for i in range(min(len(data), 4)): + result[i] = checkInt(data[i].strip(), result[i]) + return QColor(*result) return default def loadTheme(self, force: bool = False) -> bool: diff --git a/tests/test_gui/test_gui_theme.py b/tests/test_gui/test_gui_theme.py index 316f029b..f57a2c30 100644 --- a/tests/test_gui/test_gui_theme.py +++ b/tests/test_gui/test_gui_theme.py @@ -39,40 +39,6 @@ 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.""" @@ -118,7 +84,7 @@ def testGuiTheme_Main(qtbot, nwGUI, tstPaths): 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", "colour4").getRgb() == (250, 250, 0, 255) assert theme._readColor(parser, "Palette", "colour5").getRgb() == (0, 0, 0, 0) assert theme._readColor(parser, "Palette", "colour6").getRgb() == (0, 127, 255, 255) @@ -130,7 +96,7 @@ def testGuiTheme_Main(qtbot, nwGUI, tstPaths): 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) + assert theme._guiPalette.color(QPalette.ColorRole.Window).getRgb() == (250, 250, 0, 255) 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) @@ -144,6 +110,40 @@ def testGuiTheme_Main(qtbot, nwGUI, tstPaths): # qtbot.stop() +@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() == (0, 0, 0, 255) # Too long -> ignored + + # 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 @pytest.mark.skip def testGuiTheme_Theme(qtbot, monkeypatch, nwGUI, tstPaths):