diff --git a/nw/assets/icons/fallback/README.md b/nw/assets/icons/fallback/README.md
new file mode 100644
index 00000000..45a06454
--- /dev/null
+++ b/nw/assets/icons/fallback/README.md
@@ -0,0 +1,6 @@
+## License
+
+All icons in the fallback folder are modified from the Typicons theme by
+Stephen Hutchings, released under CC BY-SA 4.0.
+
+See: https://github.com/stephenhutchings/typicons.font
diff --git a/nw/assets/icons/typicons_colour_dark/globe_max.svg b/nw/assets/icons/fallback/add-dark.svg
similarity index 50%
rename from nw/assets/icons/typicons_colour_dark/globe_max.svg
rename to nw/assets/icons/fallback/add-dark.svg
index 8966c4c9..8b7f4a6d 100644
--- a/nw/assets/icons/typicons_colour_dark/globe_max.svg
+++ b/nw/assets/icons/fallback/add-dark.svg
@@ -11,23 +11,22 @@
width="24"
height="24"
viewBox="0 0 24 24"
- id="svg3369"
- sodipodi:docname="globe_max.svg"
+ id="svg5808"
+ sodipodi:docname="plus.svg"
inkscape:version="1.0rc1 (09960d6f05, 2020-04-09)">
+ id="metadata5814">
image/svg+xml
-
+ id="defs5812" />
+ inkscape:current-layer="svg5808" />
+ style="stroke-width:1.25;fill:#aeaeae;fill-opacity:1" />
diff --git a/nw/assets/icons/fallback/add.svg b/nw/assets/icons/fallback/add.svg
new file mode 100644
index 00000000..56efaa2a
--- /dev/null
+++ b/nw/assets/icons/fallback/add.svg
@@ -0,0 +1,55 @@
+
+
diff --git a/nw/assets/icons/typicons_grey_dark/globe_max.svg b/nw/assets/icons/fallback/remove-dark.svg
similarity index 50%
rename from nw/assets/icons/typicons_grey_dark/globe_max.svg
rename to nw/assets/icons/fallback/remove-dark.svg
index 8966c4c9..0cd0201c 100644
--- a/nw/assets/icons/typicons_grey_dark/globe_max.svg
+++ b/nw/assets/icons/fallback/remove-dark.svg
@@ -11,23 +11,22 @@
width="24"
height="24"
viewBox="0 0 24 24"
- id="svg3369"
- sodipodi:docname="globe_max.svg"
+ id="svg5204"
+ sodipodi:docname="minus.svg"
inkscape:version="1.0rc1 (09960d6f05, 2020-04-09)">
+ id="metadata5210">
image/svg+xml
-
+ id="defs5208" />
+ inkscape:current-layer="svg5204" />
+ style="stroke-width:1.25;fill:#aeaeae;fill-opacity:1" />
diff --git a/nw/assets/icons/fallback/remove.svg b/nw/assets/icons/fallback/remove.svg
new file mode 100644
index 00000000..77d38693
--- /dev/null
+++ b/nw/assets/icons/fallback/remove.svg
@@ -0,0 +1,55 @@
+
+
diff --git a/nw/assets/icons/fallback/search-dark.svg b/nw/assets/icons/fallback/search-dark.svg
new file mode 100644
index 00000000..5ea743b8
--- /dev/null
+++ b/nw/assets/icons/fallback/search-dark.svg
@@ -0,0 +1,58 @@
+
+
diff --git a/nw/assets/icons/fallback/search-replace-dark.svg b/nw/assets/icons/fallback/search-replace-dark.svg
new file mode 100644
index 00000000..048de135
--- /dev/null
+++ b/nw/assets/icons/fallback/search-replace-dark.svg
@@ -0,0 +1,60 @@
+
+
diff --git a/nw/assets/icons/fallback/search-replace.svg b/nw/assets/icons/fallback/search-replace.svg
new file mode 100644
index 00000000..90597a8d
--- /dev/null
+++ b/nw/assets/icons/fallback/search-replace.svg
@@ -0,0 +1,60 @@
+
+
diff --git a/nw/assets/icons/fallback/search.svg b/nw/assets/icons/fallback/search.svg
new file mode 100644
index 00000000..6ffb3f23
--- /dev/null
+++ b/nw/assets/icons/fallback/search.svg
@@ -0,0 +1,58 @@
+
+
diff --git a/nw/assets/icons/system/icons.conf b/nw/assets/icons/system/icons.conf
new file mode 100644
index 00000000..9f94d37b
--- /dev/null
+++ b/nw/assets/icons/system/icons.conf
@@ -0,0 +1,8 @@
+##
+# System Theme
+# Dummy theme that relies on Qt and novelWriter fallback icons
+##
+
+[Main]
+name = System Theme
+description = Dummy theme that relies on Qt and novelWriter fallback icons
diff --git a/nw/assets/icons/typicons_colour_dark/icons.conf b/nw/assets/icons/typicons_colour_dark/icons.conf
index dfb1278f..db622835 100644
--- a/nw/assets/icons/typicons_colour_dark/icons.conf
+++ b/nw/assets/icons/typicons_colour_dark/icons.conf
@@ -27,8 +27,6 @@ cls_custom = star.svg
cls_trash = trash.svg
proj_document = document-text.svg
proj_folder = folder.svg
-status_lang = globe_max.svg
-status_time = stopwatch_max.svg
delete = delete.svg
add = plus.svg
remove = minus.svg
diff --git a/nw/assets/icons/typicons_colour_dark/stopwatch_max.svg b/nw/assets/icons/typicons_colour_dark/stopwatch_max.svg
deleted file mode 100644
index 7d489bae..00000000
--- a/nw/assets/icons/typicons_colour_dark/stopwatch_max.svg
+++ /dev/null
@@ -1,62 +0,0 @@
-
-
diff --git a/nw/assets/icons/typicons_grey_dark/icons.conf b/nw/assets/icons/typicons_grey_dark/icons.conf
index 70cef96c..3753f2d2 100644
--- a/nw/assets/icons/typicons_grey_dark/icons.conf
+++ b/nw/assets/icons/typicons_grey_dark/icons.conf
@@ -26,8 +26,6 @@ cls_custom = star.svg
cls_trash = trash.svg
proj_document = document-text.svg
proj_folder = folder.svg
-status_lang = globe_max.svg
-status_time = stopwatch_max.svg
delete = delete.svg
add = plus.svg
remove = minus.svg
diff --git a/nw/assets/icons/typicons_grey_dark/stopwatch_max.svg b/nw/assets/icons/typicons_grey_dark/stopwatch_max.svg
deleted file mode 100644
index 7d489bae..00000000
--- a/nw/assets/icons/typicons_grey_dark/stopwatch_max.svg
+++ /dev/null
@@ -1,62 +0,0 @@
-
-
diff --git a/nw/assets/icons/typicons_grey_light/globe_max.svg b/nw/assets/icons/typicons_grey_light/globe_max.svg
deleted file mode 100644
index 255ac776..00000000
--- a/nw/assets/icons/typicons_grey_light/globe_max.svg
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
diff --git a/nw/assets/icons/typicons_grey_light/icons.conf b/nw/assets/icons/typicons_grey_light/icons.conf
index fc4d556e..1479df9e 100644
--- a/nw/assets/icons/typicons_grey_light/icons.conf
+++ b/nw/assets/icons/typicons_grey_light/icons.conf
@@ -26,8 +26,6 @@ cls_custom = star.svg
cls_trash = trash.svg
proj_document = document-text.svg
proj_folder = folder.svg
-status_lang = globe_max.svg
-status_time = stopwatch_max.svg
delete = delete.svg
add = plus.svg
remove = minus.svg
diff --git a/nw/assets/icons/typicons_grey_light/stopwatch_max.svg b/nw/assets/icons/typicons_grey_light/stopwatch_max.svg
deleted file mode 100644
index 129d58cf..00000000
--- a/nw/assets/icons/typicons_grey_light/stopwatch_max.svg
+++ /dev/null
@@ -1,61 +0,0 @@
-
-
diff --git a/nw/config.py b/nw/config.py
index e2a45e71..e0d008ee 100644
--- a/nw/config.py
+++ b/nw/config.py
@@ -84,7 +84,7 @@ class Config:
## General
self.guiTheme = "default"
self.guiSyntax = "default_light"
- self.guiIcons = "default"
+ self.guiIcons = "typicons_grey_light"
self.guiDark = False
## Sizes
diff --git a/nw/gui/icons.py b/nw/gui/icons.py
index c1a791d1..8457ea90 100644
--- a/nw/gui/icons.py
+++ b/nw/gui/icons.py
@@ -39,13 +39,31 @@ from PyQt5.QtWidgets import QStyle, qApp
logger = logging.getLogger(__name__)
class GuiIcons:
+ """The icon class manages the content of the assets/icons folder,
+ and provides a simple interface for requesting icons. Only icons
+ listed in the ICON_MAP are handled.
+
+ Icons are loaded on first request, and then cached for further
+ requests. Each icon key in the ICON_MAP has a series of fallbacks:
+ * The first lookup is in the key-to-file map for the selected icon
+ theme. The map is specified in the icons.conf file in the theme
+ folder. The map makes it possible to preserve the original file
+ name from the icon theme were the icons were extracted.
+ * Second, if the icon does not exist in the theme map, the
+ GuiIcons class will check if there is a QStyle icon specified in
+ the ICON_MAP data tuple[0]. This will let Qt pull the closest
+ system icon.
+ * Third action is to look up the freedesktop icon theme name using
+ the fromTheme Qt call. This generally produces the same results
+ as the step above, but has more icons available in other cases.
+ * Fourth, and finally, the icon is looked up in the fallback
+ folder. Files in this folder must have the same file name as the
+ novelWriter internal icon key, with '-dark' appended to it for
+ the dark background version of the icon.
+ """
- # 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 = {
+ # Project and GUI icons
"cls_none" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
"cls_novel" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
"cls_plot" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
@@ -61,7 +79,8 @@ class GuiIcons:
"status_lang" : (None, None),
"status_time" : (None, None),
"status_stats" : (None, None),
- ## Button Icons
+
+ ## General Button Icons
"folder-open" : (QStyle.SP_DirOpenIcon, "folder-open"),
"delete" : (QStyle.SP_DialogDiscardButton, "edit-delete"),
"add" : (None, "list-add"),
@@ -73,6 +92,7 @@ class GuiIcons:
"clear" : (QStyle.SP_LineEditClearButton, "clear_left"),
"save" : (QStyle.SP_DialogSaveButton, "document-save"),
"edit" : (None, None),
+
## Other Icons
"warning" : (QStyle.SP_MessageBoxWarning, "dialog-warning"),
}
@@ -117,6 +137,10 @@ class GuiIcons:
##
def updateTheme(self):
+ """Update the theme map. This is more of an init, since many of
+ the GUI icons cannot really be replaced without writing specific
+ update functions for the classes where they're used.
+ """
logger.debug("Loading icon theme files")
@@ -239,7 +263,6 @@ class GuiIcons:
self.themeList.append((themeDir, themeName))
self.themeList = sorted(self.themeList, key=lambda x: x[1])
- self.themeList.insert(0, ("default", "System Icons"))
return self.themeList
@@ -270,7 +293,8 @@ class GuiIcons:
# If we're still here, try to set from system theme
if self.ICON_MAP[iconKey][1] is not None:
logger.verbose("Loading icon '%s' from system theme" % iconKey)
- return QIcon().fromTheme(self.ICON_MAP[iconKey][1])
+ if QIcon().hasThemeIcon(self.ICON_MAP[iconKey][1]):
+ return QIcon().fromTheme(self.ICON_MAP[iconKey][1])
# Finally. we check if we have a fallback icon
if self.mainConf.guiDark:
@@ -287,6 +311,9 @@ class GuiIcons:
return QIcon()
def _parseLine(self, confParser, cnfSec, cnfName, cnfDefault):
+ """Simple wrapper for the config parser check for entry existing
+ before arrempting to load.
+ """
if confParser.has_section(cnfSec):
if confParser.has_option(cnfSec, cnfName):
return confParser.get(cnfSec, cnfName)
diff --git a/tests/reference/novelwriter.conf b/tests/reference/novelwriter.conf
index 13c3637a..53a4944a 100644
--- a/tests/reference/novelwriter.conf
+++ b/tests/reference/novelwriter.conf
@@ -2,7 +2,7 @@
timestamp = 2020-05-01 21:28:25
theme = default
syntax = default_light
-icons = default
+icons = typicons_grey_light
guidark = False
[Sizes]