Remove syntax theme parsing and add light and dark theme user settings

This commit is contained in:
Veronica Berglyd Olsen
2025-06-02 16:28:06 +02:00
parent e67ae4f3bf
commit 1fafa0dae7
6 changed files with 148 additions and 163 deletions
+11
View File
@@ -31,6 +31,7 @@ import xml.etree.ElementTree as ET
from configparser import ConfigParser
from datetime import datetime
from enum import Enum
from pathlib import Path
from typing import TYPE_CHECKING, Any, Literal, TypeGuard, TypeVar
from urllib.parse import urljoin
@@ -676,6 +677,9 @@ def openExternalPath(path: Path) -> bool:
# Classes
##
_T_Enum = TypeVar("_T_Enum", bound=Enum)
class NWConfigParser(ConfigParser):
"""Common: Adapted Config Parser
@@ -736,3 +740,10 @@ class NWConfigParser(ConfigParser):
for i in range(min(len(data), len(result))):
result[i] = checkInt(data[i].strip(), result[i])
return result
def rdEnum(self, section: str, option: str, default: _T_Enum) -> _T_Enum:
"""Read enum value."""
if self.has_option(section, option):
data = self.get(section, option, fallback="")
return type(default).__members__.get(data.upper(), default)
return default
+28 -24
View File
@@ -45,6 +45,7 @@ from novelwriter.common import (
formatTimeStamp, processDialogSymbols, simplified
)
from novelwriter.constants import nwFiles, nwHtmlUnicode, nwQuotes, nwUnicode
from novelwriter.enum import nwTheme
from novelwriter.error import formatException, logException
if TYPE_CHECKING:
@@ -55,8 +56,8 @@ if TYPE_CHECKING:
logger = logging.getLogger(__name__)
DEF_GUI = "default"
DEF_SYNTAX = "default_light"
DEF_GUI_DARK = "default_dark"
DEF_GUI_LIGHT = "default_light"
DEF_ICONS = "material_rounded_normal"
DEF_TREECOL = "theme"
@@ -69,22 +70,22 @@ class Config:
"_manuals", "_nwLangPath", "_qLocale", "_qtLangPath", "_qtTrans", "_recentPaths",
"_recentProjects", "_splash", "allowOpenDial", "altDialogClose", "altDialogOpen",
"appHandle", "appName", "askBeforeBackup", "askBeforeExit", "autoSaveDoc", "autoSaveProj",
"autoScroll", "autoScrollPos", "autoSelect", "backupOnClose", "cursorWidth", "dialogLine",
"dialogStyle", "doJustify", "doReplace", "doReplaceDQuote", "doReplaceDash",
"autoScroll", "autoScrollPos", "autoSelect", "backupOnClose", "cursorWidth", "darkTheme",
"dialogLine", "dialogStyle", "doJustify", "doReplace", "doReplaceDQuote", "doReplaceDash",
"doReplaceDots", "doReplaceSQuote", "emphLabels", "fmtApostrophe", "fmtDQuoteClose",
"fmtDQuoteOpen", "fmtPadAfter", "fmtPadBefore", "fmtPadThin", "fmtSQuoteClose",
"fmtSQuoteOpen", "focusWidth", "guiFont", "guiLocale", "guiSyntax", "guiTheme",
"hasEnchant", "hideFocusFooter", "hideHScroll", "hideVScroll", "highlightEmph", "hostName",
"iconColDocs", "iconColTree", "iconTheme", "incNotesWCount", "isDebug", "kernelVer",
"lastNotes", "mainPanePos", "mainWinSize", "memInfo", "narratorBreak", "narratorDialog",
"nativeFont", "osDarwin", "osLinux", "osType", "osUnknown", "osWindows", "outlinePanePos",
"fmtSQuoteOpen", "focusWidth", "guiFont", "guiLocale", "hasEnchant", "hideFocusFooter",
"hideHScroll", "hideVScroll", "highlightEmph", "hostName", "iconColDocs", "iconColTree",
"iconTheme", "incNotesWCount", "isDebug", "kernelVer", "lastNotes", "lightTheme",
"mainPanePos", "mainWinSize", "memInfo", "narratorBreak", "narratorDialog", "nativeFont",
"osDarwin", "osLinux", "osType", "osUnknown", "osWindows", "outlinePanePos",
"prefsWinSize", "scrollPastEnd", "searchCase", "searchLoop", "searchMatchCap",
"searchNextFile", "searchProjCase", "searchProjRegEx", "searchProjWord", "searchRegEx",
"searchWord", "showEditToolBar", "showFullPath", "showLineEndings", "showMultiSpaces",
"showSessionTime", "showTabsNSpaces", "showViewerPanel", "spellLanguage", "stopWhenIdle",
"tabWidth", "textFont", "textMargin", "textWidth", "useCharCount", "userIdleTime",
"verPyQtString", "verPyQtValue", "verPyString", "verQtString", "verQtValue",
"viewComments", "viewPanePos", "viewSynopsis", "welcomeWinSize",
"tabWidth", "textFont", "textMargin", "textWidth", "themeMode", "useCharCount",
"userIdleTime", "verPyQtString", "verPyQtValue", "verPyString", "verQtString",
"verQtValue", "viewComments", "viewPanePos", "viewSynopsis", "welcomeWinSize",
)
LANG_NW = 1
@@ -153,14 +154,15 @@ class Config:
# General GUI Settings
self.guiLocale = self._qLocale.name()
self.guiTheme = DEF_GUI # GUI theme
self.guiSyntax = DEF_SYNTAX # Syntax theme
self.guiFont = QFont() # Main GUI font
self.hideVScroll = False # Hide vertical scroll bars on main widgets
self.hideHScroll = False # Hide horizontal scroll bars on main widgets
self.lastNotes = "0x0" # The latest release notes that have been shown
self.nativeFont = True # Use native font dialog
self.useCharCount = False # Use character count as primary count
self.lightTheme = DEF_GUI_LIGHT # Light GUI theme
self.darkTheme = DEF_GUI_DARK # Dark GUI theme
self.themeMode = nwTheme.AUTO # Colour theme mode
self.guiFont = QFont() # Main GUI font
self.hideVScroll = False # Hide vertical scroll bars on main widgets
self.hideHScroll = False # Hide horizontal scroll bars on main widgets
self.lastNotes = "0x0" # The latest release notes that have been shown
self.nativeFont = True # Use native font dialog
self.useCharCount = False # Use character count as primary count
# Icons
self.iconTheme = DEF_ICONS # Icons theme
@@ -626,8 +628,9 @@ class Config:
# Main
sec = "Main"
self.setGuiFont(conf.rdStr(sec, "font", ""))
self.guiTheme = conf.rdStr(sec, "theme", self.guiTheme)
self.guiSyntax = conf.rdStr(sec, "syntax", self.guiSyntax)
self.lightTheme = conf.rdStr(sec, "lighttheme", self.lightTheme)
self.darkTheme = conf.rdStr(sec, "darktheme", self.darkTheme)
self.themeMode = conf.rdEnum(sec, "thememode", self.themeMode)
self.iconTheme = conf.rdStr(sec, "icons", self.iconTheme)
self.iconColTree = conf.rdStr(sec, "iconcoltree", self.iconColTree)
self.iconColDocs = conf.rdBool(sec, "iconcoldocs", self.iconColDocs)
@@ -751,8 +754,9 @@ class Config:
conf["Main"] = {
"font": self.guiFont.toString(),
"theme": str(self.guiTheme),
"syntax": str(self.guiSyntax),
"lighttheme": str(self.lightTheme),
"darktheme": str(self.darkTheme),
"thememode": self.themeMode.name,
"icons": str(self.iconTheme),
"iconcoltree": str(self.iconColTree),
"iconcoldocs": str(self.iconColDocs),
+25 -27
View File
@@ -35,7 +35,7 @@ from PyQt6.QtWidgets import (
from novelwriter import CONFIG, SHARED
from novelwriter.common import compact, describeFont, processDialogSymbols, uniqueCompact
from novelwriter.config import DEF_GUI, DEF_ICONS, DEF_SYNTAX, DEF_TREECOL
from novelwriter.config import DEF_GUI_DARK, DEF_GUI_LIGHT, DEF_ICONS, DEF_TREECOL
from novelwriter.constants import nwLabels, nwQuotes, nwUnicode, trConst
from novelwriter.dialogs.quotes import GuiQuoteSelect
from novelwriter.extensions.configlayout import NColorLabel, NScrollableForm
@@ -165,14 +165,24 @@ class GuiPreferences(NDialog):
)
# Colour Theme
self.guiTheme = NComboBox(self)
self.guiTheme.setMinimumWidth(200)
for theme, name in SHARED.theme.listThemes():
self.guiTheme.addItem(name, theme)
self.guiTheme.setCurrentData(CONFIG.guiTheme, DEF_GUI)
self.lightTheme = NComboBox(self)
self.lightTheme.setMinimumWidth(200)
self.darkTheme = NComboBox(self)
self.darkTheme.setMinimumWidth(200)
for theme, name, dark in SHARED.theme.listThemes():
if dark:
self.darkTheme.addItem(name, theme)
else:
self.lightTheme.addItem(name, theme)
self.lightTheme.setCurrentData(CONFIG.lightTheme, DEF_GUI_LIGHT)
self.darkTheme.setCurrentData(CONFIG.darkTheme, DEF_GUI_DARK)
self.mainForm.addRow(
self.tr("Colour theme"), self.guiTheme,
self.tr("Light colour theme"), self.lightTheme,
self.tr("User interface colour theme."), stretch=(3, 2)
)
self.mainForm.addRow(
self.tr("Dark colour theme"), self.darkTheme,
self.tr("User interface colour theme."), stretch=(3, 2)
)
@@ -242,18 +252,6 @@ class GuiPreferences(NDialog):
self.sidebar.addButton(title, section)
self.mainForm.addGroupLabel(title, section)
# Document Colour Theme
self.guiSyntax = NComboBox(self)
self.guiSyntax.setMinimumWidth(200)
for syntax, name in SHARED.theme.listSyntax():
self.guiSyntax.addItem(name, syntax)
self.guiSyntax.setCurrentData(CONFIG.guiSyntax, DEF_SYNTAX)
self.mainForm.addRow(
self.tr("Document colour theme"), self.guiSyntax,
self.tr("Colour theme for the editor and viewer."), stretch=(3, 2)
)
# Document Font Family
self.textFont = QLineEdit(self)
self.textFont.setReadOnly(True)
@@ -966,18 +964,23 @@ class GuiPreferences(NDialog):
# Appearance
guiLocale = self.guiLocale.currentData()
guiTheme = self.guiTheme.currentData()
lightTheme = self.lightTheme.currentData()
darkTheme = self.darkTheme.currentData()
iconTheme = self.iconTheme.currentData()
useCharCount = self.useCharCount.isChecked()
updateTheme |= CONFIG.guiTheme != guiTheme
updateTheme |= CONFIG.lightTheme != lightTheme
updateTheme |= CONFIG.darkTheme != darkTheme
updateTheme |= CONFIG.iconTheme != iconTheme
needsRestart |= CONFIG.guiLocale != guiLocale
needsRestart |= CONFIG.guiFont != self._guiFont
refreshTree |= CONFIG.useCharCount != useCharCount
updateSyntax |= CONFIG.lightTheme != lightTheme
updateSyntax |= CONFIG.darkTheme != darkTheme
CONFIG.guiLocale = guiLocale
CONFIG.guiTheme = guiTheme
CONFIG.lightTheme = lightTheme
CONFIG.darkTheme = darkTheme
CONFIG.iconTheme = iconTheme
CONFIG.hideVScroll = self.hideVScroll.isChecked()
CONFIG.hideHScroll = self.hideHScroll.isChecked()
@@ -986,11 +989,6 @@ class GuiPreferences(NDialog):
CONFIG.setGuiFont(self._guiFont)
# Document Style
guiSyntax = self.guiSyntax.currentData()
updateSyntax |= CONFIG.guiSyntax != guiSyntax
CONFIG.guiSyntax = guiSyntax
CONFIG.showFullPath = self.showFullPath.isChecked()
CONFIG.incNotesWCount = self.incNotesWCount.isChecked()
CONFIG.setTextFont(self._textFont)
+7
View File
@@ -156,6 +156,13 @@ class nwFocus(Enum):
OUTLINE = 3
class nwTheme(Enum):
AUTO = 0
LIGHT = 1
DARK = 2
class nwOutline(Enum):
TITLE = 0
+77 -111
View File
@@ -31,16 +31,16 @@ from typing import TYPE_CHECKING, Final
from PyQt6.QtCore import QSize, Qt
from PyQt6.QtGui import (
QColor, QFont, QFontDatabase, QFontMetrics, QIcon, QPainter, QPainterPath,
QPalette, QPixmap
QColor, QFont, QFontDatabase, QFontMetrics, QGuiApplication, QIcon,
QPainter, QPainterPath, QPalette, QPixmap
)
from PyQt6.QtWidgets import QApplication
from novelwriter import CONFIG
from novelwriter.common import NWConfigParser, minmax
from novelwriter.config import DEF_GUI, DEF_ICONS, DEF_SYNTAX
from novelwriter.config import DEF_GUI_DARK, DEF_GUI_LIGHT, DEF_ICONS
from novelwriter.constants import nwLabels
from novelwriter.enum import nwItemClass, nwItemLayout, nwItemType
from novelwriter.enum import nwItemClass, nwItemLayout, nwItemType, nwTheme
from novelwriter.error import logException
from novelwriter.types import QtBlack, QtHexArgb, QtPaintAntiAlias, QtTransparent
@@ -49,6 +49,8 @@ if TYPE_CHECKING:
logger = logging.getLogger(__name__)
T_ThemeEntry = tuple[str, str, bool]
STYLES_FLAT_TABS = "flatTabWidget"
STYLES_MIN_TOOLBUTTON = "minimalToolButton"
STYLES_BIG_TOOLBUTTON = "bigToolButton"
@@ -57,6 +59,7 @@ STYLES_BIG_TOOLBUTTON = "bigToolButton"
class ThemeMeta:
name: str = ""
mode: str = ""
description: str = ""
author: str = ""
credit: str = ""
@@ -96,13 +99,13 @@ class GuiTheme:
"""
__slots__ = (
"_availSyntax", "_availThemes", "_guiPalette", "_styleSheets", "_syntaxList", "_themeList",
"baseButtonHeight", "baseIconHeight", "baseIconSize", "buttonIconSize", "errorText",
"fadedText", "fontPixelSize", "fontPointSize", "getDecoration", "getHeaderDecoration",
"getHeaderDecorationNarrow", "getIcon", "getIconColor", "getItemIcon", "getPixmap",
"getToggleIcon", "guiFont", "guiFontB", "guiFontBU", "guiFontFixed", "guiFontSmall",
"helpText", "iconCache", "isDarkTheme", "syntaxMeta", "syntaxTheme", "textNHeight",
"textNWidth", "themeMeta",
"_availSyntax", "_availThemes", "_darkThemes", "_guiPalette", "_lightThemes",
"_styleSheets", "_syntaxList", "_themeList", "baseButtonHeight", "baseIconHeight",
"baseIconSize", "buttonIconSize", "errorText", "fadedText", "fontPixelSize",
"fontPointSize", "getDecoration", "getHeaderDecoration", "getHeaderDecorationNarrow",
"getIcon", "getIconColor", "getItemIcon", "getPixmap", "getToggleIcon", "guiFont",
"guiFontB", "guiFontBU", "guiFontFixed", "guiFontSmall", "helpText", "iconCache",
"isDarkTheme", "syntaxMeta", "syntaxTheme", "textNHeight", "textNWidth", "themeMeta",
)
def __init__(self) -> None:
@@ -124,8 +127,7 @@ class GuiTheme:
# Load Themes
self._guiPalette = QPalette()
self._themeList: list[tuple[str, str]] = []
self._syntaxList: list[tuple[str, str]] = []
self._themeList: list[T_ThemeEntry] = []
self._availThemes: dict[str, Path] = {}
self._availSyntax: dict[str, Path] = {}
self._styleSheets: dict[str, str] = {}
@@ -179,13 +181,10 @@ class GuiTheme:
logger.debug("Text 'N' Width: %d", self.textNWidth)
# Process Themes
_listConf(self._availSyntax, CONFIG.assetPath("syntax"), ".conf")
_listConf(self._availThemes, CONFIG.assetPath("themes"), ".conf")
_listConf(self._availSyntax, CONFIG.dataPath("syntax"), ".conf")
_listConf(self._availThemes, CONFIG.dataPath("themes"), ".conf")
self.loadTheme()
self.loadSyntax()
return
@@ -207,13 +206,35 @@ class GuiTheme:
# Theme Methods
##
def isDesktopDarkMode(self) -> bool:
"""Check if the desktop is in dark mode."""
if CONFIG.verQtValue >= 0x060500 and (hint := QGuiApplication.styleHints()):
return hint.colorScheme() == Qt.ColorScheme.Dark
palette = QPalette()
text = palette.color(QPalette.ColorRole.WindowText)
window = palette.color(QPalette.ColorRole.Window)
return text.lightnessF() > window.lightnessF()
def loadTheme(self) -> bool:
"""Load the currently specified GUI theme."""
theme = CONFIG.guiTheme
match CONFIG.themeMode:
case nwTheme.LIGHT:
darkMode = False
case nwTheme.DARK:
darkMode = True
case _:
darkMode = self.isDesktopDarkMode()
theme = CONFIG.darkTheme if darkMode else CONFIG.lightTheme
if theme not in self._availThemes:
logger.error("Could not find GUI theme '%s'", theme)
theme = DEF_GUI
CONFIG.guiTheme = theme
if darkMode:
theme = DEF_GUI_DARK
CONFIG.darkTheme = DEF_GUI_DARK
else:
theme = DEF_GUI_LIGHT
CONFIG.lightTheme = DEF_GUI_LIGHT
if not (file := self._availThemes.get(theme)):
logger.error("Could not load GUI theme")
@@ -238,6 +259,7 @@ class GuiTheme:
meta = ThemeMeta()
if parser.has_section(sec):
meta.name = parser.rdStr(sec, "name", "")
meta.mode = parser.rdStr(sec, "mode", "light")
meta.description = parser.rdStr(sec, "description", "N/A")
meta.author = parser.rdStr(sec, "author", "N/A")
meta.credit = parser.rdStr(sec, "credit", "N/A")
@@ -296,6 +318,31 @@ class GuiTheme:
self.fadedText = self._parseColor(parser, sec, "fadedtext")
self.errorText = self._parseColor(parser, sec, "errortext")
# Syntax
sec = "Syntax"
self.syntaxTheme = SyntaxColors()
if parser.has_section(sec):
self.syntaxTheme.back = self._parseColor(parser, sec, "background")
self.syntaxTheme.text = self._parseColor(parser, sec, "text")
self.syntaxTheme.link = self._parseColor(parser, sec, "link")
self.syntaxTheme.head = self._parseColor(parser, sec, "headertext")
self.syntaxTheme.headH = self._parseColor(parser, sec, "headertag")
self.syntaxTheme.emph = self._parseColor(parser, sec, "emphasis")
self.syntaxTheme.dialN = self._parseColor(parser, sec, "dialog")
self.syntaxTheme.dialA = self._parseColor(parser, sec, "altdialog")
self.syntaxTheme.hidden = self._parseColor(parser, sec, "hidden")
self.syntaxTheme.note = self._parseColor(parser, sec, "note")
self.syntaxTheme.code = self._parseColor(parser, sec, "shortcode")
self.syntaxTheme.key = self._parseColor(parser, sec, "keyword")
self.syntaxTheme.tag = self._parseColor(parser, sec, "tag")
self.syntaxTheme.val = self._parseColor(parser, sec, "value")
self.syntaxTheme.opt = self._parseColor(parser, sec, "optional")
self.syntaxTheme.spell = self._parseColor(parser, sec, "spellcheckline")
self.syntaxTheme.error = self._parseColor(parser, sec, "errorline")
self.syntaxTheme.repTag = self._parseColor(parser, sec, "replacetag")
self.syntaxTheme.mod = self._parseColor(parser, sec, "modifier")
self.syntaxTheme.mark = self._parseColor(parser, sec, "texthighlight")
# Update Dependant Colours
# Based on: https://github.com/qt/qtbase/blob/dev/src/gui/kernel/qplatformtheme.cpp
text = self._guiPalette.text().color()
@@ -363,105 +410,22 @@ class GuiTheme:
return True
def loadSyntax(self) -> bool:
"""Load the currently specified syntax highlighter theme."""
theme = CONFIG.guiSyntax
if theme not in self._availSyntax:
logger.error("Could not find syntax theme '%s'", theme)
theme = DEF_SYNTAX
CONFIG.guiSyntax = theme
if not (file := self._availSyntax.get(theme)):
logger.error("Could not load syntax theme")
return False
CONFIG.splashMessage("Loading syntax theme ...")
logger.info("Loading syntax theme '%s'", theme)
parser = NWConfigParser()
try:
with open(file, mode="r", encoding="utf-8") as fo:
parser.read_file(fo)
except Exception:
logger.error("Could not read file: %s", file)
logException()
return False
# Main
sec = "Main"
meta = ThemeMeta()
if parser.has_section(sec):
meta.name = parser.rdStr(sec, "name", "")
meta.description = parser.rdStr(sec, "description", "N/A")
meta.author = parser.rdStr(sec, "author", "N/A")
meta.credit = parser.rdStr(sec, "credit", "N/A")
meta.url = parser.rdStr(sec, "url", "")
meta.license = parser.rdStr(sec, "license", "N/A")
meta.licenseUrl = parser.rdStr(sec, "licenseurl", "")
# Syntax
sec = "Syntax"
syntax = SyntaxColors()
if parser.has_section(sec):
syntax.back = self._parseColor(parser, sec, "background")
syntax.text = self._parseColor(parser, sec, "text")
syntax.link = self._parseColor(parser, sec, "link")
syntax.head = self._parseColor(parser, sec, "headertext")
syntax.headH = self._parseColor(parser, sec, "headertag")
syntax.emph = self._parseColor(parser, sec, "emphasis")
syntax.dialN = self._parseColor(parser, sec, "dialog")
syntax.dialA = self._parseColor(parser, sec, "altdialog")
syntax.hidden = self._parseColor(parser, sec, "hidden")
syntax.note = self._parseColor(parser, sec, "note")
syntax.code = self._parseColor(parser, sec, "shortcode")
syntax.key = self._parseColor(parser, sec, "keyword")
syntax.tag = self._parseColor(parser, sec, "tag")
syntax.val = self._parseColor(parser, sec, "value")
syntax.opt = self._parseColor(parser, sec, "optional")
syntax.spell = self._parseColor(parser, sec, "spellcheckline")
syntax.error = self._parseColor(parser, sec, "errorline")
syntax.repTag = self._parseColor(parser, sec, "replacetag")
syntax.mod = self._parseColor(parser, sec, "modifier")
syntax.mark = self._parseColor(parser, sec, "texthighlight")
CONFIG.splashMessage(f"Loaded syntax theme: {meta.name}")
self.syntaxMeta = meta
self.syntaxTheme = syntax
return True
def listThemes(self) -> list[tuple[str, str]]:
def listThemes(self) -> list[T_ThemeEntry]:
"""Scan the GUI themes folder and list all themes."""
if self._themeList:
return self._themeList
themes = []
themes: list[T_ThemeEntry] = []
parser = NWConfigParser()
for key, path in self._availThemes.items():
logger.debug("Checking theme config '%s'", key)
if name := _loadInternalName(parser, path):
themes.append((key, name))
if meta := _loadInternalName(parser, path):
themes.append((key, meta[0], meta[1]))
self._themeList = sorted(themes, key=_sortTheme)
return self._themeList
def listSyntax(self) -> list[tuple[str, str]]:
"""Scan the syntax themes folder and list all themes."""
if self._syntaxList:
return self._syntaxList
themes = []
parser = NWConfigParser()
for key, path in self._availSyntax.items():
logger.debug("Checking theme syntax '%s'", key)
if name := _loadInternalName(parser, path):
themes.append((key, name))
self._syntaxList = sorted(themes, key=_sortTheme)
return self._syntaxList
def getStyleSheet(self, name: str) -> str:
"""Load a standard style sheet."""
return self._styleSheets.get(name, "")
@@ -889,22 +853,24 @@ def _listConf(target: dict, path: Path, extension: str) -> None:
return
def _sortTheme(data: tuple[str, str]) -> str:
def _sortTheme(data: tuple) -> str:
"""Key function for theme sorting."""
key, name = data
key, name = data[:2]
return f"*{name}" if key.startswith("default_") else name
def _loadInternalName(parser: NWConfigParser, path: str | Path) -> str:
def _loadInternalName(parser: NWConfigParser, path: str | Path) -> tuple[str, bool]:
"""Open a conf file and read the 'name' setting."""
try:
with open(path, mode="r", encoding="utf-8") as inFile:
parser.read_file(inFile)
return parser.rdStr("Main", "name", "")
name = parser.rdStr("Main", "name", "")
dark = parser.rdStr("Main", "mode", "light").lower() == "dark"
return name, dark
except Exception:
logger.error("Could not read file: %s", path)
logException()
return ""
return "", False
def _loadIconName(path: Path) -> str:
-1
View File
@@ -1069,7 +1069,6 @@ class GuiMain(QMainWindow):
SHARED.project.tree.refreshAllItems()
if syntax:
SHARED.theme.loadSyntax()
self.docEditor.updateSyntaxColors()
self.docEditor.initEditor()