diff --git a/MANIFEST.in b/MANIFEST.in index f46cec23..024e5f29 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,2 @@ include LICENSE.md recursive-include nw/assets * -recursive-include nw/graphics * -recursive-include nw/themes * diff --git a/install.py b/install.py index 00d6ac00..14356f23 100755 --- a/install.py +++ b/install.py @@ -65,7 +65,7 @@ instOpt = [ "--onefile", "--add-data=%s%s%s" % (os.path.join("nw", "themes"), dotDot,"themes"), "--add-data=%s%s%s" % (os.path.join("nw", "graphics"),dotDot,"graphics"), - "--icon=%s" % os.path.join("nw", "graphics", "novelWriter.ico"), + "--icon=%s" % os.path.join("nw", "assets", "icons", "novelWriter.ico"), ] if buildWindowed: instOpt.append("--windowed") diff --git a/nw/graphics/export.svg b/nw/assets/graphics/export.svg similarity index 100% rename from nw/graphics/export.svg rename to nw/assets/graphics/export.svg diff --git a/nw/graphics/export.txt b/nw/assets/graphics/export.txt similarity index 100% rename from nw/graphics/export.txt rename to nw/assets/graphics/export.txt diff --git a/nw/graphics/gear.svg b/nw/assets/graphics/gear.svg similarity index 100% rename from nw/graphics/gear.svg rename to nw/assets/graphics/gear.svg diff --git a/nw/graphics/novelWriter.ico b/nw/assets/icons/novelWriter.ico similarity index 100% rename from nw/graphics/novelWriter.ico rename to nw/assets/icons/novelWriter.ico diff --git a/nw/graphics/novelWriter.svg b/nw/assets/icons/novelWriter.svg similarity index 100% rename from nw/graphics/novelWriter.svg rename to nw/assets/icons/novelWriter.svg diff --git a/nw/themes/gui/default/style.qss b/nw/assets/themes/gui/default/style.qss similarity index 100% rename from nw/themes/gui/default/style.qss rename to nw/assets/themes/gui/default/style.qss diff --git a/nw/themes/gui/default/theme.conf b/nw/assets/themes/gui/default/theme.conf similarity index 100% rename from nw/themes/gui/default/theme.conf rename to nw/assets/themes/gui/default/theme.conf diff --git a/nw/themes/gui/default_dark/icons/add.png b/nw/assets/themes/gui/default_dark/icons/add.png similarity index 100% rename from nw/themes/gui/default_dark/icons/add.png rename to nw/assets/themes/gui/default_dark/icons/add.png diff --git a/nw/themes/gui/default_dark/icons/close.png b/nw/assets/themes/gui/default_dark/icons/close.png similarity index 100% rename from nw/themes/gui/default_dark/icons/close.png rename to nw/assets/themes/gui/default_dark/icons/close.png diff --git a/nw/themes/gui/default_dark/icons/document.png b/nw/assets/themes/gui/default_dark/icons/document.png similarity index 100% rename from nw/themes/gui/default_dark/icons/document.png rename to nw/assets/themes/gui/default_dark/icons/document.png diff --git a/nw/themes/gui/default_dark/icons/folder.png b/nw/assets/themes/gui/default_dark/icons/folder.png similarity index 100% rename from nw/themes/gui/default_dark/icons/folder.png rename to nw/assets/themes/gui/default_dark/icons/folder.png diff --git a/nw/themes/gui/default_dark/icons/orphan.png b/nw/assets/themes/gui/default_dark/icons/orphan.png similarity index 100% rename from nw/themes/gui/default_dark/icons/orphan.png rename to nw/assets/themes/gui/default_dark/icons/orphan.png diff --git a/nw/themes/gui/default_dark/icons/remove.png b/nw/assets/themes/gui/default_dark/icons/remove.png similarity index 100% rename from nw/themes/gui/default_dark/icons/remove.png rename to nw/assets/themes/gui/default_dark/icons/remove.png diff --git a/nw/themes/gui/default_dark/icons/replace.png b/nw/assets/themes/gui/default_dark/icons/replace.png similarity index 100% rename from nw/themes/gui/default_dark/icons/replace.png rename to nw/assets/themes/gui/default_dark/icons/replace.png diff --git a/nw/themes/gui/default_dark/icons/root.png b/nw/assets/themes/gui/default_dark/icons/root.png similarity index 100% rename from nw/themes/gui/default_dark/icons/root.png rename to nw/assets/themes/gui/default_dark/icons/root.png diff --git a/nw/themes/gui/default_dark/icons/save.png b/nw/assets/themes/gui/default_dark/icons/save.png similarity index 100% rename from nw/themes/gui/default_dark/icons/save.png rename to nw/assets/themes/gui/default_dark/icons/save.png diff --git a/nw/themes/gui/default_dark/icons/search.png b/nw/assets/themes/gui/default_dark/icons/search.png similarity index 100% rename from nw/themes/gui/default_dark/icons/search.png rename to nw/assets/themes/gui/default_dark/icons/search.png diff --git a/nw/themes/gui/default_dark/icons/trash.png b/nw/assets/themes/gui/default_dark/icons/trash.png similarity index 100% rename from nw/themes/gui/default_dark/icons/trash.png rename to nw/assets/themes/gui/default_dark/icons/trash.png diff --git a/nw/themes/gui/default_dark/styles.qss b/nw/assets/themes/gui/default_dark/styles.qss similarity index 100% rename from nw/themes/gui/default_dark/styles.qss rename to nw/assets/themes/gui/default_dark/styles.qss diff --git a/nw/themes/gui/default_dark/theme.conf b/nw/assets/themes/gui/default_dark/theme.conf similarity index 100% rename from nw/themes/gui/default_dark/theme.conf rename to nw/assets/themes/gui/default_dark/theme.conf diff --git a/nw/themes/syntax/default_dark.conf b/nw/assets/themes/syntax/default_dark.conf similarity index 100% rename from nw/themes/syntax/default_dark.conf rename to nw/assets/themes/syntax/default_dark.conf diff --git a/nw/themes/syntax/default_light.conf b/nw/assets/themes/syntax/default_light.conf similarity index 100% rename from nw/themes/syntax/default_light.conf rename to nw/assets/themes/syntax/default_light.conf diff --git a/nw/themes/syntax/light_owl.conf b/nw/assets/themes/syntax/light_owl.conf similarity index 100% rename from nw/themes/syntax/light_owl.conf rename to nw/assets/themes/syntax/light_owl.conf diff --git a/nw/themes/syntax/night_owl.conf b/nw/assets/themes/syntax/night_owl.conf similarity index 100% rename from nw/themes/syntax/night_owl.conf rename to nw/assets/themes/syntax/night_owl.conf diff --git a/nw/themes/syntax/tomorrow.conf b/nw/assets/themes/syntax/tomorrow.conf similarity index 100% rename from nw/themes/syntax/tomorrow.conf rename to nw/assets/themes/syntax/tomorrow.conf diff --git a/nw/themes/syntax/tomorrow_night.conf b/nw/assets/themes/syntax/tomorrow_night.conf similarity index 100% rename from nw/themes/syntax/tomorrow_night.conf rename to nw/assets/themes/syntax/tomorrow_night.conf diff --git a/nw/themes/syntax/tomorrow_night_blue.conf b/nw/assets/themes/syntax/tomorrow_night_blue.conf similarity index 100% rename from nw/themes/syntax/tomorrow_night_blue.conf rename to nw/assets/themes/syntax/tomorrow_night_blue.conf diff --git a/nw/themes/syntax/tomorrow_night_bright.conf b/nw/assets/themes/syntax/tomorrow_night_bright.conf similarity index 100% rename from nw/themes/syntax/tomorrow_night_bright.conf rename to nw/assets/themes/syntax/tomorrow_night_bright.conf diff --git a/nw/themes/syntax/tomorrow_night_eighties.conf b/nw/assets/themes/syntax/tomorrow_night_eighties.conf similarity index 100% rename from nw/themes/syntax/tomorrow_night_eighties.conf rename to nw/assets/themes/syntax/tomorrow_night_eighties.conf diff --git a/nw/config.py b/nw/config.py index 7047354b..340cab38 100644 --- a/nw/config.py +++ b/nw/config.py @@ -54,6 +54,7 @@ class Config: self.themeRoot = None self.graphPath = None self.dictPath = None + self.iconPath = None # Set default values self.confChanged = False @@ -61,6 +62,7 @@ class Config: ## General self.guiTheme = "default" self.guiSyntax = "default_light" + self.guiDark = False ## Sizes self.winGeometry = [1100, 650] @@ -172,10 +174,11 @@ class Config: self.appPath = getattr(sys, "_MEIPASS", path.abspath(path.dirname(__file__))) self.appRoot = path.join(self.appPath,path.pardir) self.assetPath = path.join(self.appPath,"assets") - self.themeRoot = path.join(self.appPath,"themes") - self.graphPath = path.join(self.appPath,"graphics") + self.themeRoot = path.join(self.assetPath,"themes") + self.graphPath = path.join(self.assetPath,"graphics") self.dictPath = path.join(self.assetPath,"dict") - self.appIcon = path.join(self.graphPath, nwFiles.APP_ICON) + self.iconPath = path.join(self.assetPath,"icons") + self.appIcon = path.join(self.iconPath, nwFiles.APP_ICON) # If config folder does not exist, make it. # This assumes that the os config folder itself exists. @@ -224,6 +227,9 @@ class Config: self.guiSyntax = self._parseLine( cnfParse, cnfSec, "syntax", self.CNF_STR, self.guiSyntax ) + self.guiDark = self._parseLine( + cnfParse, cnfSec, "guidark", self.CNF_BOOL, self.guiDark + ) ## Sizes cnfSec = "Sizes" @@ -358,6 +364,7 @@ class Config: cnfParse.set(cnfSec,"timestamp", datetime.now().strftime("%Y-%m-%d %H:%M:%S")) cnfParse.set(cnfSec,"theme", str(self.guiTheme)) cnfParse.set(cnfSec,"syntax", str(self.guiSyntax)) + cnfParse.set(cnfSec,"guidark", str(self.guiDark)) ## Sizes cnfSec = "Sizes" diff --git a/nw/gui/__init__.py b/nw/gui/__init__.py index a755fc97..b8196cc2 100644 --- a/nw/gui/__init__.py +++ b/nw/gui/__init__.py @@ -1,8 +1,10 @@ # -*- coding: utf-8 -*- # Main Window Elements +from nw.gui.icons import GuiIcons from nw.gui.mainmenu import GuiMainMenu from nw.gui.statusbar import GuiMainStatus +from nw.gui.theme import GuiTheme # Dialogs from nw.gui.dialogs.configeditor import GuiConfigEditor @@ -26,8 +28,10 @@ from nw.gui.tools.dochighlight import GuiDocHighlighter from nw.gui.tools.wordcounter import WordCounter __all__ = [ + "GuiIcons", "GuiMainMenu", "GuiMainStatus", + "GuiTheme", "GuiConfigEditor", "GuiExport", "GuiItemEditor", diff --git a/nw/gui/dialogs/configeditor.py b/nw/gui/dialogs/configeditor.py index bc809282..24c509bf 100644 --- a/nw/gui/dialogs/configeditor.py +++ b/nw/gui/dialogs/configeditor.py @@ -15,8 +15,7 @@ import nw from os import path -from PyQt5.QtCore import Qt, QSize -from PyQt5.QtSvg import QSvgWidget +from PyQt5.QtCore import Qt from PyQt5.QtGui import ( QIcon, QPixmap, QColor, QBrush, QStandardItemModel, QFont ) @@ -46,10 +45,7 @@ class GuiConfigEditor(QDialog): self.innerBox = QVBoxLayout() self.setWindowTitle("Preferences") - - self.gradPath = path.abspath(path.join(self.mainConf.graphPath,"gear.svg")) - self.svgGradient = QSvgWidget(path.join(self.gradPath)) - self.svgGradient.setFixedSize(QSize(64,64)) + self.guiDeco = self.theParent.theTheme.loadDecoration("settings",(64,64)) self.theProject.countStatus() self.tabMain = GuiConfigEditGeneral(self.theParent) @@ -60,7 +56,7 @@ class GuiConfigEditor(QDialog): self.tabWidget.addTab(self.tabEditor, "Editor") self.setLayout(self.outerBox) - self.outerBox.addWidget(self.svgGradient, 0, Qt.AlignTop) + self.outerBox.addWidget(self.guiDeco, 0, Qt.AlignTop) self.outerBox.addLayout(self.innerBox) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) @@ -147,11 +143,16 @@ class GuiConfigEditGeneral(QWidget): if syntaxIdx != -1: self.guiLookSyntax.setCurrentIndex(syntaxIdx) + self.guiDarkIcons = QCheckBox("Prefer icons for dark backgrounds", self) + self.guiDarkIcons.setToolTip("This may improve the look of icons if the system theme is dark.") + self.guiDarkIcons.setChecked(self.mainConf.guiDark) + self.guiLookForm.addWidget(QLabel("Theme"), 0, 0) self.guiLookForm.addWidget(self.guiLookTheme, 0, 1) self.guiLookForm.addWidget(QLabel("Syntax"), 1, 0) self.guiLookForm.addWidget(self.guiLookSyntax, 1, 1) - self.guiLookForm.setColumnStretch(2, 1) + self.guiLookForm.addWidget(self.guiDarkIcons, 2, 0, 1, 2) + self.guiLookForm.setColumnStretch(3, 1) # Spell Checking self.spellLang = QGroupBox("Spell Checker", self) @@ -221,17 +222,11 @@ class GuiConfigEditGeneral(QWidget): self.projBackupClose = QCheckBox("Run on close",self) self.projBackupClose.setToolTip("Backup automatically on project close.") - if self.mainConf.backupOnClose: - self.projBackupClose.setCheckState(Qt.Checked) - else: - self.projBackupClose.setCheckState(Qt.Unchecked) + self.projBackupClose.setChecked(self.mainConf.backupOnClose) self.projBackupAsk = QCheckBox("Ask before backup",self) self.projBackupAsk.setToolTip("Ask before backup.") - if self.mainConf.askBeforeBackup: - self.projBackupAsk.setCheckState(Qt.Checked) - else: - self.projBackupAsk.setCheckState(Qt.Unchecked) + self.projBackupAsk.setChecked(self.mainConf.askBeforeBackup) self.projBackupForm.addWidget(self.projBackupPath, 0, 0, 1, 2) self.projBackupForm.addWidget(self.projBackupGetPath, 0, 2) @@ -257,6 +252,7 @@ class GuiConfigEditGeneral(QWidget): guiTheme = self.guiLookTheme.currentData() guiSyntax = self.guiLookSyntax.currentData() + guiDark = self.guiDarkIcons.isChecked() spellTool = self.spellToolList.currentData() spellLanguage = self.spellLangList.currentData() autoSaveDoc = self.autoSaveDoc.value() @@ -270,6 +266,7 @@ class GuiConfigEditGeneral(QWidget): self.mainConf.guiTheme = guiTheme self.mainConf.guiSyntax = guiSyntax + self.mainConf.guiDark = guiDark self.mainConf.spellTool = spellTool self.mainConf.spellLanguage = spellLanguage self.mainConf.autoSaveDoc = autoSaveDoc diff --git a/nw/gui/dialogs/export.py b/nw/gui/dialogs/export.py index c3053ff0..b3944f74 100644 --- a/nw/gui/dialogs/export.py +++ b/nw/gui/dialogs/export.py @@ -16,8 +16,7 @@ import nw from os import path -from PyQt5.QtCore import Qt, QSize -from PyQt5.QtSvg import QSvgWidget +from PyQt5.QtCore import Qt from PyQt5.QtWidgets import ( QDialog, QHBoxLayout, QVBoxLayout, QWidget, QTabWidget, QGridLayout, QGroupBox, QCheckBox, QLabel, QComboBox, QLineEdit, QPushButton, @@ -50,9 +49,7 @@ class GuiExport(QDialog): self.setWindowTitle("Export Project") self.setLayout(self.outerBox) - self.gradPath = path.abspath(path.join(self.mainConf.graphPath,"export.svg")) - self.svgGradient = QSvgWidget(self.gradPath) - self.svgGradient.setFixedSize(QSize(64,64)) + self.guiDeco = self.theParent.theTheme.loadDecoration("export",(64,64)) self.theProject.countStatus() self.tabMain = GuiExportMain(self.theParent, self.theProject, self.optState) @@ -62,7 +59,7 @@ class GuiExport(QDialog): self.tabWidget.addTab(self.tabMain, "Settings") self.tabWidget.addTab(self.tabPandoc, "Pandoc") - self.outerBox.addWidget(self.svgGradient, 0, Qt.AlignTop) + self.outerBox.addWidget(self.guiDeco, 0, Qt.AlignTop) self.outerBox.addLayout(self.innerBox) self.doExportForm = QGridLayout() diff --git a/nw/gui/dialogs/itemeditor.py b/nw/gui/dialogs/itemeditor.py index f099a32d..af6fa609 100644 --- a/nw/gui/dialogs/itemeditor.py +++ b/nw/gui/dialogs/itemeditor.py @@ -15,8 +15,7 @@ import nw from os import path -from PyQt5.QtCore import Qt, QSize -from PyQt5.QtSvg import QSvgWidget +from PyQt5.QtCore import Qt from PyQt5.QtWidgets import ( QDialog, QHBoxLayout, QVBoxLayout, QGroupBox, QFormLayout, QLineEdit, QPushButton, QComboBox @@ -42,13 +41,10 @@ class GuiItemEditor(QDialog): self.innerBox = QVBoxLayout() self.setWindowTitle("Item Settings") - - self.gradPath = path.abspath(path.join(self.mainConf.graphPath,"gear.svg")) - self.svgGradient = QSvgWidget(self.gradPath) - self.svgGradient.setFixedSize(QSize(64,64)) + self.guiDeco = self.theParent.theTheme.loadDecoration("settings",(64,64)) self.setLayout(self.outerBox) - self.outerBox.addWidget(self.svgGradient, 0, Qt.AlignTop) + self.outerBox.addWidget(self.guiDeco, 0, Qt.AlignTop) self.outerBox.addLayout(self.innerBox) self.mainGroup = QGroupBox("Item Settings") diff --git a/nw/gui/dialogs/projecteditor.py b/nw/gui/dialogs/projecteditor.py index 1db212f6..0c6d8fae 100644 --- a/nw/gui/dialogs/projecteditor.py +++ b/nw/gui/dialogs/projecteditor.py @@ -15,9 +15,8 @@ import nw from os import path -from PyQt5.QtCore import Qt, QSize -from PyQt5.QtGui import QIcon, QPixmap, QColor, QBrush, QStandardItemModel -from PyQt5.QtSvg import QSvgWidget +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QIcon, QPixmap, QColor, QBrush from PyQt5.QtWidgets import ( QDialog, QHBoxLayout, QVBoxLayout, QFormLayout, QLineEdit, QPlainTextEdit, QLabel, QWidget, QTabWidget, QDialogButtonBox, QListWidget, @@ -45,9 +44,7 @@ class GuiProjectEditor(QDialog): self.setWindowTitle("Project Settings") self.setLayout(self.outerBox) - self.gradPath = path.abspath(path.join(self.mainConf.graphPath,"gear.svg")) - self.svgGradient = QSvgWidget(self.gradPath) - self.svgGradient.setFixedSize(QSize(64,64)) + self.guiDeco = self.theParent.theTheme.loadDecoration("settings",(64,64)) self.theProject.countStatus() self.tabMain = GuiProjectEditMain(self.theParent, self.theProject) @@ -61,7 +58,7 @@ class GuiProjectEditor(QDialog): self.tabWidget.addTab(self.tabImport, "Importance") self.tabWidget.addTab(self.tabReplace,"Auto-Replace") - self.outerBox.addWidget(self.svgGradient, 0, Qt.AlignTop) + self.outerBox.addWidget(self.guiDeco, 0, Qt.AlignTop) self.outerBox.addLayout(self.innerBox) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) diff --git a/nw/gui/icons.py b/nw/gui/icons.py new file mode 100644 index 00000000..c44f84e5 --- /dev/null +++ b/nw/gui/icons.py @@ -0,0 +1,151 @@ +# -*- coding: utf-8 -*- +"""novelWriter Icons Class + + novelWriter – Icons Class +=========================== + This class manages the GUI icons + + File History: + Created: 2019-11-08 [0.4.0] + +""" + +import logging +import nw + +from os import path + +from PyQt5.QtCore import QSize +from PyQt5.QtSvg import QSvgWidget +from PyQt5.QtGui import QIcon + +logger = logging.getLogger(__name__) + +class GuiIcons: + + # Icon keys should either be a .svg or .png file under the gui + # theme folder, or have a fallback that is either compatible with + # QIcon.fromTheme, as specified here: + # https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html + # or, if there is no fallback, the variable should be None. + ICON_MAP = { + "root" : "drive-harddisk", + "folder" : "folder", + "document" : "x-office-document", + "trash" : "user-trash", + "orphan" : "dialog-warning", + "save" : "document-save", + "add" : "list-add", + "remove" : "list-remove", + "close" : "edit-delete", + "search" : "edit-find", + "replace" : "edit-find-replace", + "time" : None, + } + + DECO_MAP = { + "export" : "export.svg", + "settings" : "settings.svg", + } + + def __init__(self, theParent): + + self.mainConf = nw.CONFIG + self.theParent = theParent + + # Storage + self.qIcons = {} + + # Look for files in + self.priPath = "" # The gui theme's icon folder + self.secPath = "" # The main assets icon folder + self.prefDark = False # Load dark icons, if available + + return + + def initIcons(self, priPath): + + self.priPath = priPath + self.secPath = self.mainConf.iconPath + self.prefDark = self.mainConf.guiDark + + for iconKey in self.ICON_MAP.keys(): + self.qIcons[iconKey] = self._loadIcon(iconKey) + + return + + def loadDecoration(self, decoKey, decoSize=None): + + if decoKey not in self.DECO_MAP: + logger.error("Decoration with name '%s' does not exist" % decoKey) + return QSvgWidget() + + svgPath = path.join(self.mainConf.graphPath, self.DECO_MAP[decoKey]) + if not path.isfile(svgPath): + logger.error("Decoration file '%s' not in assets folder" % self.DECO_MAP[decoKey]) + return QSvgWidget() + + svgDeco = QSvgWidget(svgPath) + if decoSize is not None: + svgDeco.setFixedSize(QSize(decoSize[0],decoSize[1])) + + return svgDeco + + def getIcon(self, iconKey, iconSize=None): + if iconKey in self.qIcons: + return self.qIcons[iconKey] + return QIcon() + + ## + # Internal Functions + ## + + def _loadIcon(self, iconKey): + + if iconKey not in self.ICON_MAP: + logger.error("Icon with name '%s' does not exist" % iconKey) + return QIcon() + + if self.prefDark: + iconSuffix = "dark" + else: + iconSuffix = "light" + + iconNames = [] + iconNames.append("%s-%s.svg" % (iconKey, iconSuffix)) + iconNames.append("%s-%s.png" % (iconKey, iconSuffix)) + iconNames.append("%s.svg" % iconKey) + iconNames.append("%s.png" % iconKey) + + # Check theme folder + loadFrom = None + for iconName in iconNames: + checkPath = path.join(self.priPath, iconName) + if path.isfile(checkPath): + loadFrom = checkPath + logger.verbose("Loading icon '%s' from theme" % iconName) + break + if loadFrom is not None: + return QIcon(loadFrom) + + # Check assets folder + for iconName in iconNames: + checkPath = path.join(self.secPath, iconName) + if path.isfile(checkPath): + loadFrom = checkPath + logger.verbose("Loading icon '%s' from assets" % iconName) + break + if loadFrom is not None: + return QIcon(loadFrom) + + # If we're still here, try to set from system theme + if self.ICON_MAP[iconKey] is not None: + logger.verbose("Loading icon '%s' from system theme" % iconKey) + return QIcon().fromTheme(self.ICON_MAP[iconKey]) + + # Give up and return an empty icomn + logger.warning("Did not load an icon for '%s'" % iconKey) + + return QIcon() + +# END Class GuiIcons diff --git a/nw/theme.py b/nw/gui/theme.py similarity index 90% rename from nw/theme.py rename to nw/gui/theme.py index 5c05c0dd..bf6a0121 100644 --- a/nw/theme.py +++ b/nw/gui/theme.py @@ -20,29 +20,17 @@ from PyQt5.QtWidgets import qApp from PyQt5.QtGui import QPalette, QColor, QIcon, QPixmap from nw.constants import nwAlert +from nw.gui.icons import GuiIcons logger = logging.getLogger(__name__) -class Theme: - - ICON_MAP = { - "root" : "drive-harddisk", - "folder" : "folder", - "document" : "x-office-document", - "trash" : "user-trash", - "orphan" : "dialog-warning", - "save" : "document-save", - "add" : "list-add", - "remove" : "list-remove", - "close" : "edit-delete", - "search" : "edit-find", - "replace" : "edit-find-replace", - } +class GuiTheme: def __init__(self, theParent): self.mainConf = nw.CONFIG self.theParent = theParent + self.theIcons = GuiIcons(self.theParent) self.guiPalette = QPalette() self.guiPath = "gui" self.iconPath = "icons" @@ -91,9 +79,6 @@ class Theme: self.colTagErr = [ 0, 0, 0] self.colRepTag = [ 0, 0, 0] - ## Icons - self.themeIcons = {} - # Changeable Settings self.guiTheme = None self.guiSyntax = None @@ -105,6 +90,9 @@ class Theme: self.updateTheme() + self.getIcon = self.theIcons.getIcon + self.loadDecoration = self.theIcons.loadDecoration + return ## @@ -121,8 +109,7 @@ class Theme: self.confFile = path.join(self.themePath,self.confName) self.cssFile = path.join(self.themePath,self.cssName) - for iconName in self.ICON_MAP: - self.themeIcons[iconName] = QIcon.fromTheme(self.ICON_MAP[iconName]) + self.theIcons.initIcons(path.join(self.themePath,self.iconPath)) self.loadTheme() self.loadSyntax() @@ -132,6 +119,7 @@ class Theme: def loadTheme(self): logger.debug("Loading theme files") + logger.debug("System icon theme is '%s'" % str(QIcon.themeName())) # CSS File cssData = "" @@ -143,14 +131,6 @@ class Theme: logger.error("Could not load theme css file") return False - # Icon Files - iconsDir = path.join(self.themePath,self.iconPath) - if path.isdir(iconsDir): - for iconName in self.ICON_MAP: - iconFile = path.join(iconsDir,iconName+".png") - if path.isfile(iconFile): - self.themeIcons[iconName] = QIcon(iconFile) - # Config File confParser = configparser.ConfigParser() try: @@ -294,16 +274,6 @@ class Theme: return self.syntaxList - def getIcon(self, iconName, iconSize=None): - if iconName in self.themeIcons: - return self.themeIcons[iconName] - return QIcon() - - def getIconPixmap(self, iconName, iconSize=None): - if iconName in self.themeIcons: - return self.themeIcons[iconName].pixmap() - return QPixmap() - ## # Internal Functions ## @@ -345,4 +315,4 @@ class Theme: return confParser.get(cnfSec, cnfName) return cnfDefault -# End Class Theme +# End Class GuiTheme diff --git a/nw/guimain.py b/nw/guimain.py index b42b4070..169fa42f 100644 --- a/nw/guimain.py +++ b/nw/guimain.py @@ -24,14 +24,13 @@ from PyQt5.QtWidgets import ( ) from nw.gui import ( - GuiMainMenu, GuiMainStatus, GuiDocTree, GuiDocEditor, GuiDocViewer, - GuiDocDetails, GuiSearchBar, GuiNoticeBar, GuiDocViewDetails, - GuiConfigEditor, GuiProjectEditor, GuiExport, GuiItemEditor, - GuiTimeLineView, GuiSessionLogView + GuiMainMenu, GuiMainStatus, GuiTheme, GuiDocTree, GuiDocEditor, + GuiDocViewer, GuiDocDetails, GuiSearchBar, GuiNoticeBar, + GuiDocViewDetails, GuiConfigEditor, GuiProjectEditor, GuiExport, + GuiItemEditor, GuiTimeLineView, GuiSessionLogView ) from nw.project import NWProject, NWDoc, NWItem, NWIndex, NWBackup from nw.tools import countWords -from nw.theme import Theme from nw.constants import nwFiles, nwItemType, nwAlert logger = logging.getLogger(__name__) @@ -44,7 +43,7 @@ class GuiMain(QMainWindow): logger.info("Starting %s" % nw.__package__) logger.debug("Initialising GUI ...") self.mainConf = nw.CONFIG - self.theTheme = Theme(self) + self.theTheme = GuiTheme(self) self.theProject = NWProject(self) self.theIndex = NWIndex(self.theProject, self) self.hasProject = False diff --git a/tests/reference/novelwriter.conf b/tests/reference/novelwriter.conf index f6e1ea90..239301e1 100644 --- a/tests/reference/novelwriter.conf +++ b/tests/reference/novelwriter.conf @@ -1,7 +1,8 @@ [Main] -timestamp = 2019-11-08 00:27:54 +timestamp = 2019-11-08 18:43:21 theme = default syntax = default_light +guidark = False [Sizes] geometry = 1100, 650