From ec1047207c1ff19334aca2fe685aaf8184fc05ec Mon Sep 17 00:00:00 2001
From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com>
Date: Fri, 10 Jan 2025 17:39:20 +0100
Subject: [PATCH 1/6] Restructure how icon themes are generated
---
pkgutils.py | 16 ++-
utils/icon_themes.py | 270 ++++++++++++++++++++++++++++++++++++
utils/material_icons.py | 186 -------------------------
utils/material_symbols.json | 105 ++++++++++++++
4 files changed, 387 insertions(+), 190 deletions(-)
create mode 100644 utils/icon_themes.py
delete mode 100644 utils/material_icons.py
create mode 100644 utils/material_symbols.json
diff --git a/pkgutils.py b/pkgutils.py
index 060a1220e..aa4ddad6c 100755
--- a/pkgutils.py
+++ b/pkgutils.py
@@ -35,7 +35,7 @@
from pathlib import Path
-from utils.material_icons import processMaterialIcons
+from utils.icon_themes import processFontAwesome, processMaterialIcons
CURR_DIR = Path(__file__).parent
SETUP_DIR = CURR_DIR / "setup"
@@ -330,10 +330,10 @@ def buildSampleZip(args: argparse.Namespace | None = None) -> None:
##
def buildIconTheme(args: argparse.Namespace) -> None:
- """Build an icon theme."""
+ """Build icon themes."""
print("")
- print("Build Icon Theme")
- print("================")
+ print("Build Icon Themes")
+ print("=================")
print("")
workDir = Path(args.sources).absolute()
@@ -384,6 +384,14 @@ def buildIconTheme(args: argparse.Namespace) -> None:
},
})
+ if style in ("all", "fa"):
+ processFontAwesome(workDir, iconsDir, {
+ "font_awesome": {
+ "name": "Font Awesome 6",
+ },
+ })
+
+ print("Done")
print("")
return
diff --git a/utils/icon_themes.py b/utils/icon_themes.py
new file mode 100644
index 000000000..1371debde
--- /dev/null
+++ b/utils/icon_themes.py
@@ -0,0 +1,270 @@
+"""
+novelWriter – Icon Theme Utils
+==============================
+
+This file is a part of novelWriter
+Copyright (C) 2025 Veronica Berglyd Olsen and novelWriter contributors
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+"""
+from __future__ import annotations
+
+import json
+import subprocess
+
+from pathlib import Path
+from xml.etree import ElementTree as ET
+
+UTILS = Path(__file__).parent
+
+ET.register_namespace("", "http://www.w3.org/2000/svg")
+MATERIAL_REPO = "https://github.com/google/material-design-icons.git"
+FONT_AWESOME_REPO = "https://github.com/FortAwesome/Font-Awesome.git"
+ICONS = [
+ "alert_error",
+ "alert_info",
+ "alert_question",
+ "alert_warn",
+
+ "cls_archive",
+ "cls_character",
+ "cls_custom",
+ "cls_entity",
+ "cls_none",
+ "cls_novel",
+ "cls_object",
+ "cls_plot",
+ "cls_template",
+ "cls_timeline",
+ "cls_trash",
+ "cls_world",
+
+ "prj_folder",
+ "prj_document",
+ "prj_title",
+ "prj_chapter",
+ "prj_scene",
+ "prj_note",
+
+ "fmt_bold",
+ "fmt_italic",
+ "fmt_mark",
+ "fmt_strike",
+ "fmt_subscript",
+ "fmt_superscript",
+ "fmt_underline",
+ "fmt_toolbar",
+
+ "search",
+ "search_cancel",
+ "search_case",
+ "search_loop",
+ "search_preserve",
+ "search_project",
+ "search_regex",
+ "search_replace",
+ "search_word",
+
+ "bullet-off",
+ "bullet-on",
+ "unfold-hide",
+ "unfold-show",
+
+ "add",
+ "bookmarks",
+ "browse",
+ "cancel",
+ "checked",
+ "chevron_down",
+ "chevron_left",
+ "chevron_right",
+ "chevron_up",
+ "close",
+ "copy",
+ "document_add",
+ "document",
+ "edit",
+ "exclude",
+ "export",
+ "filter",
+ "fit_height",
+ "fit_width",
+ "folder",
+ "font",
+ "import",
+ "language",
+ "lines",
+ "list",
+ "manuscript",
+ "margin_bottom",
+ "margin_left",
+ "margin_right",
+ "margin_top",
+ "maximise",
+ "minimise",
+ "more_arrow",
+ "more_vertical",
+ "noncheckable",
+ "novel_view",
+ "open",
+ "outline",
+ "panel",
+ "pin",
+ "project_copy",
+ "project_view",
+ "quote",
+ "refresh",
+ "remove",
+ "revert",
+ "settings",
+ "star",
+ "stats",
+ "text",
+ "timer_off",
+ "timer",
+ "unchecked",
+ "view",
+]
+
+
+def _loadMap(name: str) -> dict[str, str]:
+ """Load a theme map file."""
+ data = json.loads((UTILS / f"{name}.json").read_text(encoding="utf-8"))
+ icons = {}
+ for key in ICONS:
+ if icon := data.get(key, ""):
+ icons[key] = icon
+ else:
+ print(f"- Missing: {key}")
+ return icons
+
+
+def _fixXml(svg: ET.Element) -> str:
+ """Clean up the SVG XML and add needed fields."""
+ svg.set("fill", "#000000")
+ svg.set("height", "128")
+ svg.set("width", "128")
+ return ET.tostring(svg).decode()
+
+
+def _writeThemeFile(
+ path: Path, name: str, author: str, license: str, icons: dict[str, ET.Element]
+) -> None:
+ """Write an icon theme file."""
+ with open(path.with_suffix(".icons"), mode="w", encoding="utf-8") as out:
+ out.write("# This file is automatically generated. Do not edit.\n\n")
+ out.write("# Meta\n")
+ out.write(f"meta:name = {name}\n")
+ out.write(f"meta:author = {author}\n")
+ out.write(f"meta:license = {license}\n")
+ out.write("\n")
+ out.write("# Icons\n")
+ for key, svg in icons.items():
+ out.write(f"icon:{key:<15s} = {_fixXml(svg)}\n")
+ print(f"- Wrote: {len(icons)} icons")
+ print(f"- Target: {path.relative_to(UTILS.parent)}")
+ return
+
+
+def _cloneRepo(repoPath: Path, repoUrl: str) -> None:
+ """Clone or update a local repo of icons."""
+ print(f"Updating: {repoUrl}")
+ if not repoPath.is_dir():
+ subprocess.call(["git", "clone", repoUrl, "--depth", "50"], cwd=repoPath.parent)
+ else:
+ subprocess.call(["git", "pull"], cwd=repoPath)
+ print("")
+ return
+
+
+def processMaterialIcons(workDir: Path, iconsDir: Path, jobs: dict) -> None:
+ """Process material icons of a given spec and write output file."""
+ srcRepo = workDir / "material-design-icons"
+ _cloneRepo(srcRepo, MATERIAL_REPO)
+
+ for file, job in jobs.items():
+ name: str = job["name"]
+ style: str = job["style"]
+ filled: bool = job["filled"]
+ weight: int = job["weight"]
+
+ kind = f"wght{weight}" if weight != 400 else ""
+ kind += "fill1" if filled else ""
+
+ print(f"Processing: {name}")
+
+ icons: dict[str, ET.Element] = {}
+ iconSrc = srcRepo / "symbols" / "web"
+ for key, icon in _loadMap("material_symbols").items():
+ if kind:
+ fileNmae = f"{icon}_{kind}_24px.svg"
+ else:
+ fileNmae = f"{icon}_24px.svg"
+ iconFile = iconSrc / icon / f"materialsymbols{style}" / fileNmae
+ if iconFile.is_file():
+ icons[key] = ET.fromstring(iconFile.read_text(encoding="utf-8"))
+ else:
+ print(f"Not Found: {iconFile}")
+
+ target = iconsDir / f"{file}.icons"
+ _writeThemeFile(target, name, "Google Inc", "Apache 2.0", icons)
+
+ print("")
+
+ return
+
+
+def processFontAwesome(workDir: Path, iconsDir: Path, jobs: dict) -> None:
+ """Process Font Awesome icons of a given spec and write output file."""
+ srcRepo = workDir / "Font-Awesome"
+ _cloneRepo(srcRepo, FONT_AWESOME_REPO)
+
+ for file, job in jobs.items():
+ name: str = job["name"]
+ print(f"Processing: {name}")
+
+ icons: dict[str, ET.Element] = {}
+ iconSrc = srcRepo / "svgs"
+ for key, value in _loadMap("font_awesome").items():
+ icon, _, forced = value.partition(":")
+ iconSolid = iconSrc / "solid" / f"{icon}.svg"
+ iconRegular = iconSrc / "regular" / f"{icon}.svg"
+ if forced == "regular":
+ iconFile = iconRegular
+ elif forced == "solid":
+ iconFile = iconSolid
+ elif iconSolid.is_file():
+ iconFile = iconSolid
+ elif iconRegular.is_file():
+ iconFile = iconRegular
+ else:
+ print(f"Not Found: {icon}.svg")
+ continue
+
+ if iconFile.is_file():
+ svg = ET.fromstring(iconFile.read_text(encoding="utf-8"))
+ viewbox = [int(x) for x in svg.get("viewBox", "").split()]
+ viewbox = [viewbox[2]//2 - 256, 0, 512, 512]
+ svg.set("viewBox", " ".join(str(x) for x in viewbox))
+ icons[key] = svg
+ else:
+ print(f"Not Found: {icon}.svg")
+ continue
+
+ target = iconsDir / f"{file}.icons"
+ _writeThemeFile(target, name, "Fonticons Inc", "Font Awesome Free License", icons)
+
+ print("")
+
+ return
diff --git a/utils/material_icons.py b/utils/material_icons.py
deleted file mode 100644
index b57219d2b..000000000
--- a/utils/material_icons.py
+++ /dev/null
@@ -1,186 +0,0 @@
-"""
-novelWriter – Material Icon Theme
-=================================
-
-This file is a part of novelWriter
-Copyright (C) 2025 Veronica Berglyd Olsen and novelWriter contributors
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-"""
-from __future__ import annotations
-
-import subprocess
-
-from pathlib import Path
-from xml.etree import ElementTree as ET
-
-ET.register_namespace("", "http://www.w3.org/2000/svg")
-MATERIAL_REPO = "https://github.com/google/material-design-icons.git"
-ICON_MAP = {
- "alert_error": "error",
- "alert_info": "info",
- "alert_question": "help",
- "alert_warn": "warning",
-
- "cls_archive": "archive",
- "cls_character": "group",
- "cls_custom": "label",
- "cls_entity": "apartment",
- "cls_none": "close",
- "cls_novel": "book_2",
- "cls_object": "key",
- "cls_plot": "extension",
- "cls_template": "topic",
- "cls_timeline": "hourglass_empty",
- "cls_trash": "delete",
- "cls_world": "globe",
-
- "prj_folder": "folder",
- "prj_document": "news",
- "prj_title": "news",
- "prj_chapter": "news",
- "prj_scene": "news",
- "prj_note": "sticky_note_2",
-
- "fmt_bold": "format_bold",
- "fmt_italic": "format_italic",
- "fmt_mark": "format_ink_highlighter",
- "fmt_strike": "strikethrough_s",
- "fmt_subscript": "subscript",
- "fmt_superscript": "superscript",
- "fmt_underline": "format_underlined",
- "fmt_toolbar": "text_format",
-
- "search": "search",
- "search_cancel": "close",
- "search_case": "match_case",
- "search_loop": "laps",
- "search_preserve": "text_fields",
- "search_project": "document_search",
- "search_regex": "regular_expression",
- "search_replace": "find_replace",
- "search_word": "match_word",
-
- "bullet-off": "radio_button_unchecked",
- "bullet-on": "radio_button_checked",
- "unfold-hide": "arrow_right",
- "unfold-show": "arrow_drop_down",
-
- "add": "add",
- "bookmarks": "bookmarks",
- "browse": "folder_open",
- "cancel": "cancel",
- "checked": "check_box",
- "chevron_down": "keyboard_arrow_down",
- "chevron_left": "arrow_back_ios",
- "chevron_right": "arrow_forward_ios",
- "chevron_up": "keyboard_arrow_up",
- "close": "close",
- "copy": "content_copy",
- "document_add": "note_add",
- "document": "docs",
- "edit": "edit",
- "exclude": "do_not_disturb_on",
- "export": "file_export",
- "filter": "filter_alt",
- "fit_height": "fit_page_height",
- "fit_width": "fit_page_width",
- "folder": "folder",
- "font": "font_download",
- "import": "tab_move",
- "language": "translate",
- "lines": "reorder",
- "list": "format_list_bulleted",
- "manuscript": "export_notes",
- "margin_bottom": "vertical_align_bottom",
- "margin_left": "keyboard_tab_rtl",
- "margin_right": "keyboard_tab",
- "margin_top": "vertical_align_top",
- "maximise": "fullscreen",
- "minimise": "fullscreen_exit",
- "more_arrow": "arrow_right",
- "more_vertical": "more_vert",
- "noncheckable": "indeterminate_check_box",
- "novel_view": "book_4_spark",
- "open": "open_in_new",
- "outline": "summarize",
- "panel": "dock_to_bottom",
- "pin": "keep",
- "project_copy": "folder_copy",
- "project_view": "bookmark_manager",
- "quote": "format_quote",
- "refresh": "refresh",
- "remove": "remove",
- "revert": "settings_backup_restore",
- "settings": "settings",
- "star": "star",
- "stats": "bar_chart",
- "text": "subject",
- "timer_off": "timer_off",
- "timer": "timer",
- "unchecked": "disabled_by_default",
- "view": "visibility",
-}
-
-
-def _fixXml(svg: str) -> str:
- """Clean up the SVG XML and add needed fields."""
- xSvg = ET.fromstring(svg)
- xSvg.set("fill", "#000000")
- xSvg.set("height", "128")
- xSvg.set("width", "128")
- return ET.tostring(xSvg).decode()
-
-
-def processMaterialIcons(workDir: Path, iconsDir: Path, jobs: dict) -> None:
- """Process material icons of a given spec and write output file."""
- srcRepo = workDir / "material-design-icons"
- if not srcRepo.is_dir():
- subprocess.call(["git", "clone", MATERIAL_REPO, "--depth", "50"], cwd=workDir)
- else:
- subprocess.call(["git", "pull"], cwd=srcRepo)
-
- for file, job in jobs.items():
- name: str = job["name"]
- style: str = job["style"]
- filled: bool = job["filled"]
- weight: int = job["weight"]
-
- kind = f"wght{weight}" if weight != 400 else ""
- kind += "fill1" if filled else ""
-
- print("")
- print(f"Processing: {name}")
- print("")
- with open(iconsDir / f"{file}.icons", mode="w", encoding="utf-8") as icons:
- icons.write("# This file is automatically generated. Do not edit.\n\n")
- icons.write("# Meta\n")
- icons.write(f"meta:name = {name}\n")
- icons.write("meta:author = Google Inc\n")
- icons.write("meta:license = Apache 2.0\n")
- icons.write("\n")
- icons.write("# Icons\n")
- iconSrc = srcRepo / "symbols" / "web"
- for key, icon in ICON_MAP.items():
- if kind:
- fileNmae = f"{icon}_{kind}_24px.svg"
- else:
- fileNmae = f"{icon}_24px.svg"
- iconFile = iconSrc / icon / f"materialsymbols{style}" / fileNmae
- if iconFile.is_file():
- svg = iconFile.read_text(encoding="utf-8")
- icons.write(f"icon:{key:<15s} = {_fixXml(svg)}\n")
- print(f"Wrote: {iconFile.stem}")
- else:
- print(f"Not Found: {iconFile}")
diff --git a/utils/material_symbols.json b/utils/material_symbols.json
new file mode 100644
index 000000000..7abb89244
--- /dev/null
+++ b/utils/material_symbols.json
@@ -0,0 +1,105 @@
+{
+ "alert_error": "error",
+ "alert_info": "info",
+ "alert_question": "help",
+ "alert_warn": "warning",
+
+ "cls_archive": "archive",
+ "cls_character": "group",
+ "cls_custom": "label",
+ "cls_entity": "apartment",
+ "cls_none": "close",
+ "cls_novel": "book_2",
+ "cls_object": "key",
+ "cls_plot": "extension",
+ "cls_template": "topic",
+ "cls_timeline": "hourglass_empty",
+ "cls_trash": "delete",
+ "cls_world": "globe",
+
+ "prj_folder": "folder",
+ "prj_document": "news",
+ "prj_title": "news",
+ "prj_chapter": "news",
+ "prj_scene": "news",
+ "prj_note": "sticky_note_2",
+
+ "fmt_bold": "format_bold",
+ "fmt_italic": "format_italic",
+ "fmt_mark": "format_ink_highlighter",
+ "fmt_strike": "strikethrough_s",
+ "fmt_subscript": "subscript",
+ "fmt_superscript": "superscript",
+ "fmt_underline": "format_underlined",
+ "fmt_toolbar": "text_format",
+
+ "search": "search",
+ "search_cancel": "close",
+ "search_case": "match_case",
+ "search_loop": "laps",
+ "search_preserve": "text_fields",
+ "search_project": "document_search",
+ "search_regex": "regular_expression",
+ "search_replace": "find_replace",
+ "search_word": "match_word",
+
+ "bullet-off": "radio_button_unchecked",
+ "bullet-on": "radio_button_checked",
+ "unfold-hide": "arrow_right",
+ "unfold-show": "arrow_drop_down",
+
+ "add": "add",
+ "bookmarks": "bookmarks",
+ "browse": "folder_open",
+ "cancel": "cancel",
+ "checked": "check_box",
+ "chevron_down": "keyboard_arrow_down",
+ "chevron_left": "arrow_back_ios",
+ "chevron_right": "arrow_forward_ios",
+ "chevron_up": "keyboard_arrow_up",
+ "close": "close",
+ "copy": "content_copy",
+ "document_add": "note_add",
+ "document": "docs",
+ "edit": "edit",
+ "exclude": "do_not_disturb_on",
+ "export": "file_export",
+ "filter": "filter_alt",
+ "fit_height": "fit_page_height",
+ "fit_width": "fit_page_width",
+ "folder": "folder",
+ "font": "font_download",
+ "import": "tab_move",
+ "language": "translate",
+ "lines": "reorder",
+ "list": "format_list_bulleted",
+ "manuscript": "export_notes",
+ "margin_bottom": "vertical_align_bottom",
+ "margin_left": "keyboard_tab_rtl",
+ "margin_right": "keyboard_tab",
+ "margin_top": "vertical_align_top",
+ "maximise": "fullscreen",
+ "minimise": "fullscreen_exit",
+ "more_arrow": "arrow_right",
+ "more_vertical": "more_vert",
+ "noncheckable": "indeterminate_check_box",
+ "novel_view": "book_4_spark",
+ "open": "open_in_new",
+ "outline": "summarize",
+ "panel": "dock_to_bottom",
+ "pin": "keep",
+ "project_copy": "folder_copy",
+ "project_view": "bookmark_manager",
+ "quote": "format_quote",
+ "refresh": "refresh",
+ "remove": "remove",
+ "revert": "settings_backup_restore",
+ "settings": "settings",
+ "star": "star",
+ "stats": "bar_chart",
+ "text": "subject",
+ "timer_off": "timer_off",
+ "timer": "timer",
+ "unchecked": "disabled_by_default",
+ "view": "visibility"
+}
From 723cba5b561806caf75172706d2fd13075c62413 Mon Sep 17 00:00:00 2001
From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com>
Date: Fri, 10 Jan 2025 17:40:02 +0100
Subject: [PATCH 2/6] Separate out icons for sidebar
---
.../assets/icons/material_filled_bold.icons | 196 +++++++++---------
.../assets/icons/material_filled_normal.icons | 196 +++++++++---------
.../assets/icons/material_filled_thin.icons | 196 +++++++++---------
.../assets/icons/material_rounded_bold.icons | 196 +++++++++---------
.../icons/material_rounded_normal.icons | 196 +++++++++---------
.../assets/icons/material_rounded_thin.icons | 196 +++++++++---------
novelwriter/gui/sidebar.py | 10 +-
utils/icon_themes.py | 9 +-
utils/material_symbols.json | 9 +-
9 files changed, 611 insertions(+), 593 deletions(-)
diff --git a/novelwriter/assets/icons/material_filled_bold.icons b/novelwriter/assets/icons/material_filled_bold.icons
index 4abcebf4f..37c790471 100644
--- a/novelwriter/assets/icons/material_filled_bold.icons
+++ b/novelwriter/assets/icons/material_filled_bold.icons
@@ -6,100 +6,102 @@ meta:author = Google Inc
meta:license = Apache 2.0
# Icons
-icon:alert_error =
-icon:alert_info =
-icon:alert_question =
-icon:alert_warn =
-icon:cls_archive =
-icon:cls_character =
-icon:cls_custom =
-icon:cls_entity =
-icon:cls_none =
-icon:cls_novel =
-icon:cls_object =
-icon:cls_plot =
-icon:cls_template =
-icon:cls_timeline =
-icon:cls_trash =
-icon:cls_world =
-icon:prj_folder =
-icon:prj_document =
-icon:prj_title =
-icon:prj_chapter =
-icon:prj_scene =
-icon:prj_note =
-icon:fmt_bold =
-icon:fmt_italic =
-icon:fmt_mark =
-icon:fmt_strike =
-icon:fmt_subscript =
-icon:fmt_superscript =
-icon:fmt_underline =
-icon:fmt_toolbar =
-icon:search =
-icon:search_cancel =
-icon:search_case =
-icon:search_loop =
-icon:search_preserve =
-icon:search_project =
-icon:search_regex =
-icon:search_replace =
-icon:search_word =
-icon:bullet-off =
-icon:bullet-on =
-icon:unfold-hide =
-icon:unfold-show =
-icon:add =
-icon:bookmarks =
-icon:browse =
-icon:cancel =
-icon:checked =
-icon:chevron_down =
-icon:chevron_left =
-icon:chevron_right =
-icon:chevron_up =
-icon:close =
-icon:copy =
-icon:document_add =
-icon:document =
-icon:edit =
-icon:exclude =
-icon:export =
-icon:filter =
-icon:fit_height =
-icon:fit_width =
-icon:folder =
-icon:font =
-icon:import =
-icon:language =
-icon:lines =
-icon:list =
-icon:manuscript =
-icon:margin_bottom =
-icon:margin_left =
-icon:margin_right =
-icon:margin_top =
-icon:maximise =
-icon:minimise =
-icon:more_arrow =
-icon:more_vertical =
-icon:noncheckable =
-icon:novel_view =
-icon:open =
-icon:outline =
-icon:panel =
-icon:pin =
-icon:project_copy =
-icon:project_view =
-icon:quote =
-icon:refresh =
-icon:remove =
-icon:revert =
-icon:settings =
-icon:star =
-icon:stats =
-icon:text =
-icon:timer_off =
-icon:timer =
-icon:unchecked =
-icon:view =
+icon:alert_error =
+icon:alert_info =
+icon:alert_question =
+icon:alert_warn =
+icon:cls_archive =
+icon:cls_character =
+icon:cls_custom =
+icon:cls_entity =
+icon:cls_none =
+icon:cls_novel =
+icon:cls_object =
+icon:cls_plot =
+icon:cls_template =
+icon:cls_timeline =
+icon:cls_trash =
+icon:cls_world =
+icon:prj_folder =
+icon:prj_document =
+icon:prj_title =
+icon:prj_chapter =
+icon:prj_scene =
+icon:prj_note =
+icon:fmt_bold =
+icon:fmt_italic =
+icon:fmt_mark =
+icon:fmt_strike =
+icon:fmt_subscript =
+icon:fmt_superscript =
+icon:fmt_underline =
+icon:fmt_toolbar =
+icon:search =
+icon:search_cancel =
+icon:search_case =
+icon:search_loop =
+icon:search_preserve =
+icon:search_project =
+icon:search_regex =
+icon:search_replace =
+icon:search_word =
+icon:bullet-off =
+icon:bullet-on =
+icon:unfold-hide =
+icon:unfold-show =
+icon:sb_project =
+icon:sb_novel =
+icon:sb_search =
+icon:sb_outline =
+icon:sb_build =
+icon:add =
+icon:bookmarks =
+icon:browse =
+icon:cancel =
+icon:checked =
+icon:chevron_down =
+icon:chevron_left =
+icon:chevron_right =
+icon:chevron_up =
+icon:close =
+icon:copy =
+icon:document_add =
+icon:document =
+icon:edit =
+icon:exclude =
+icon:export =
+icon:filter =
+icon:fit_height =
+icon:fit_width =
+icon:folder =
+icon:font =
+icon:import =
+icon:language =
+icon:lines =
+icon:list =
+icon:manuscript =
+icon:margin_bottom =
+icon:margin_left =
+icon:margin_right =
+icon:margin_top =
+icon:maximise =
+icon:minimise =
+icon:more_arrow =
+icon:more_vertical =
+icon:noncheckable =
+icon:open =
+icon:panel =
+icon:pin =
+icon:project_copy =
+icon:quote =
+icon:refresh =
+icon:remove =
+icon:revert =
+icon:settings =
+icon:star =
+icon:stats =
+icon:text =
+icon:timer_off =
+icon:timer =
+icon:unchecked =
+icon:view =
diff --git a/novelwriter/assets/icons/material_filled_normal.icons b/novelwriter/assets/icons/material_filled_normal.icons
index 53e88c4cf..155b0507d 100644
--- a/novelwriter/assets/icons/material_filled_normal.icons
+++ b/novelwriter/assets/icons/material_filled_normal.icons
@@ -6,100 +6,102 @@ meta:author = Google Inc
meta:license = Apache 2.0
# Icons
-icon:alert_error =
-icon:alert_info =
-icon:alert_question =
-icon:alert_warn =
-icon:cls_archive =
-icon:cls_character =
-icon:cls_custom =
-icon:cls_entity =
-icon:cls_none =
-icon:cls_novel =
-icon:cls_object =
-icon:cls_plot =
-icon:cls_template =
-icon:cls_timeline =
-icon:cls_trash =
-icon:cls_world =
-icon:prj_folder =
-icon:prj_document =
-icon:prj_title =
-icon:prj_chapter =
-icon:prj_scene =
-icon:prj_note =
-icon:fmt_bold =
-icon:fmt_italic =
-icon:fmt_mark =
-icon:fmt_strike =
-icon:fmt_subscript =
-icon:fmt_superscript =
-icon:fmt_underline =
-icon:fmt_toolbar =
-icon:search =
-icon:search_cancel =
-icon:search_case =
-icon:search_loop =
-icon:search_preserve =
-icon:search_project =
-icon:search_regex =
-icon:search_replace =
-icon:search_word =
-icon:bullet-off =
-icon:bullet-on =
-icon:unfold-hide =
-icon:unfold-show =
-icon:add =
-icon:bookmarks =
-icon:browse =
-icon:cancel =
-icon:checked =
-icon:chevron_down =
-icon:chevron_left =
-icon:chevron_right =
-icon:chevron_up =
-icon:close =
-icon:copy =
-icon:document_add =
-icon:document =
-icon:edit =
-icon:exclude =
-icon:export =
-icon:filter =
-icon:fit_height =
-icon:fit_width =
-icon:folder =
-icon:font =
-icon:import =
-icon:language =
-icon:lines =
-icon:list =
-icon:manuscript =
-icon:margin_bottom =
-icon:margin_left =
-icon:margin_right =
-icon:margin_top =
-icon:maximise =
-icon:minimise =
-icon:more_arrow =
-icon:more_vertical =
-icon:noncheckable =
-icon:novel_view =
-icon:open =
-icon:outline =
-icon:panel =
-icon:pin =
-icon:project_copy =
-icon:project_view =
-icon:quote =
-icon:refresh =
-icon:remove =
-icon:revert =
-icon:settings =
-icon:star =
-icon:stats =
-icon:text =
-icon:timer_off =
-icon:timer =
-icon:unchecked =
-icon:view =
+icon:alert_error =
+icon:alert_info =
+icon:alert_question =
+icon:alert_warn =
+icon:cls_archive =
+icon:cls_character =
+icon:cls_custom =
+icon:cls_entity =
+icon:cls_none =
+icon:cls_novel =
+icon:cls_object =
+icon:cls_plot =
+icon:cls_template =
+icon:cls_timeline =
+icon:cls_trash =
+icon:cls_world =
+icon:prj_folder =
+icon:prj_document =
+icon:prj_title =
+icon:prj_chapter =
+icon:prj_scene =
+icon:prj_note =
+icon:fmt_bold =
+icon:fmt_italic =
+icon:fmt_mark =
+icon:fmt_strike =
+icon:fmt_subscript =
+icon:fmt_superscript =
+icon:fmt_underline =
+icon:fmt_toolbar =
+icon:search =
+icon:search_cancel =
+icon:search_case =
+icon:search_loop =
+icon:search_preserve =
+icon:search_project =
+icon:search_regex =
+icon:search_replace =
+icon:search_word =
+icon:bullet-off =
+icon:bullet-on =
+icon:unfold-hide =
+icon:unfold-show =
+icon:sb_project =
+icon:sb_novel =
+icon:sb_search =
+icon:sb_outline =
+icon:sb_build =
+icon:add =
+icon:bookmarks =
+icon:browse =
+icon:cancel =
+icon:checked =
+icon:chevron_down =
+icon:chevron_left =
+icon:chevron_right =
+icon:chevron_up =
+icon:close =
+icon:copy =
+icon:document_add =
+icon:document =
+icon:edit =
+icon:exclude =
+icon:export =
+icon:filter =
+icon:fit_height =
+icon:fit_width =
+icon:folder =
+icon:font =
+icon:import =
+icon:language =
+icon:lines =
+icon:list =
+icon:manuscript =
+icon:margin_bottom =
+icon:margin_left =
+icon:margin_right =
+icon:margin_top =
+icon:maximise =
+icon:minimise =
+icon:more_arrow =
+icon:more_vertical =
+icon:noncheckable =
+icon:open =
+icon:panel =
+icon:pin =
+icon:project_copy =
+icon:quote =
+icon:refresh =
+icon:remove =
+icon:revert =
+icon:settings =
+icon:star =
+icon:stats =
+icon:text =
+icon:timer_off =
+icon:timer =
+icon:unchecked =
+icon:view =
diff --git a/novelwriter/assets/icons/material_filled_thin.icons b/novelwriter/assets/icons/material_filled_thin.icons
index 43a60e8db..a04942fdc 100644
--- a/novelwriter/assets/icons/material_filled_thin.icons
+++ b/novelwriter/assets/icons/material_filled_thin.icons
@@ -6,100 +6,102 @@ meta:author = Google Inc
meta:license = Apache 2.0
# Icons
-icon:alert_error =
-icon:alert_info =
-icon:alert_question =
-icon:alert_warn =
-icon:cls_archive =
-icon:cls_character =
-icon:cls_custom =
-icon:cls_entity =
-icon:cls_none =
-icon:cls_novel =
-icon:cls_object =
-icon:cls_plot =
-icon:cls_template =
-icon:cls_timeline =
-icon:cls_trash =
-icon:cls_world =
-icon:prj_folder =
-icon:prj_document =
-icon:prj_title =
-icon:prj_chapter =
-icon:prj_scene =
-icon:prj_note =
-icon:fmt_bold =
-icon:fmt_italic =
-icon:fmt_mark =
-icon:fmt_strike =
-icon:fmt_subscript =
-icon:fmt_superscript =
-icon:fmt_underline =
-icon:fmt_toolbar =
-icon:search =
-icon:search_cancel =
-icon:search_case =
-icon:search_loop =
-icon:search_preserve =
-icon:search_project =
-icon:search_regex =
-icon:search_replace =
-icon:search_word =
-icon:bullet-off =
-icon:bullet-on =
-icon:unfold-hide =
-icon:unfold-show =
-icon:add =
-icon:bookmarks =
-icon:browse =
-icon:cancel =
-icon:checked =
-icon:chevron_down =
-icon:chevron_left =
-icon:chevron_right =
-icon:chevron_up =
-icon:close =
-icon:copy =
-icon:document_add =
-icon:document =
-icon:edit =
-icon:exclude =
-icon:export =
-icon:filter =
-icon:fit_height =
-icon:fit_width =
-icon:folder =
-icon:font =
-icon:import =
-icon:language =
-icon:lines =
-icon:list =
-icon:manuscript =
-icon:margin_bottom =
-icon:margin_left =
-icon:margin_right =
-icon:margin_top =
-icon:maximise =
-icon:minimise =
-icon:more_arrow =
-icon:more_vertical =
-icon:noncheckable =
-icon:novel_view =
-icon:open =
-icon:outline =
-icon:panel =
-icon:pin =
-icon:project_copy =
-icon:project_view =
-icon:quote =
-icon:refresh =
-icon:remove =
-icon:revert =
-icon:settings =
-icon:star =
-icon:stats =
-icon:text =
-icon:timer_off =
-icon:timer =
-icon:unchecked =
-icon:view =
+icon:alert_error =
+icon:alert_info =
+icon:alert_question =
+icon:alert_warn =
+icon:cls_archive =
+icon:cls_character =
+icon:cls_custom =
+icon:cls_entity =
+icon:cls_none =
+icon:cls_novel =
+icon:cls_object =
+icon:cls_plot =
+icon:cls_template =
+icon:cls_timeline =
+icon:cls_trash =
+icon:cls_world =
+icon:prj_folder =
+icon:prj_document =
+icon:prj_title =
+icon:prj_chapter =
+icon:prj_scene =
+icon:prj_note =
+icon:fmt_bold =
+icon:fmt_italic =
+icon:fmt_mark =
+icon:fmt_strike =
+icon:fmt_subscript =
+icon:fmt_superscript =
+icon:fmt_underline =
+icon:fmt_toolbar =
+icon:search =
+icon:search_cancel =
+icon:search_case =
+icon:search_loop =
+icon:search_preserve =
+icon:search_project =
+icon:search_regex =
+icon:search_replace =
+icon:search_word =
+icon:bullet-off =
+icon:bullet-on =
+icon:unfold-hide =
+icon:unfold-show =
+icon:sb_project =
+icon:sb_novel =
+icon:sb_search =
+icon:sb_outline =
+icon:sb_build =
+icon:add =
+icon:bookmarks =
+icon:browse =
+icon:cancel =
+icon:checked =
+icon:chevron_down =
+icon:chevron_left =
+icon:chevron_right =
+icon:chevron_up =
+icon:close =
+icon:copy =
+icon:document_add =
+icon:document =
+icon:edit =
+icon:exclude =
+icon:export =
+icon:filter =
+icon:fit_height =
+icon:fit_width =
+icon:folder =
+icon:font =
+icon:import =
+icon:language =
+icon:lines =
+icon:list =
+icon:manuscript =
+icon:margin_bottom =
+icon:margin_left =
+icon:margin_right =
+icon:margin_top =
+icon:maximise =
+icon:minimise =
+icon:more_arrow =
+icon:more_vertical =
+icon:noncheckable =
+icon:open =
+icon:panel =
+icon:pin =
+icon:project_copy =
+icon:quote =
+icon:refresh =
+icon:remove =
+icon:revert =
+icon:settings =
+icon:star =
+icon:stats =
+icon:text =
+icon:timer_off =
+icon:timer =
+icon:unchecked =
+icon:view =
diff --git a/novelwriter/assets/icons/material_rounded_bold.icons b/novelwriter/assets/icons/material_rounded_bold.icons
index 30297456f..71602cb7f 100644
--- a/novelwriter/assets/icons/material_rounded_bold.icons
+++ b/novelwriter/assets/icons/material_rounded_bold.icons
@@ -6,100 +6,102 @@ meta:author = Google Inc
meta:license = Apache 2.0
# Icons
-icon:alert_error =
-icon:alert_info =
-icon:alert_question =
-icon:alert_warn =
-icon:cls_archive =
-icon:cls_character =
-icon:cls_custom =
-icon:cls_entity =
-icon:cls_none =
-icon:cls_novel =
-icon:cls_object =
-icon:cls_plot =
-icon:cls_template =
-icon:cls_timeline =
-icon:cls_trash =
-icon:cls_world =
-icon:prj_folder =
-icon:prj_document =
-icon:prj_title =
-icon:prj_chapter =
-icon:prj_scene =
-icon:prj_note =
-icon:fmt_bold =
-icon:fmt_italic =
-icon:fmt_mark =
-icon:fmt_strike =
-icon:fmt_subscript =
-icon:fmt_superscript =
-icon:fmt_underline =
-icon:fmt_toolbar =
-icon:search =
-icon:search_cancel =
-icon:search_case =
-icon:search_loop =
-icon:search_preserve =
-icon:search_project =
-icon:search_regex =
-icon:search_replace =
-icon:search_word =
-icon:bullet-off =
-icon:bullet-on =
-icon:unfold-hide =
-icon:unfold-show =
-icon:add =
-icon:bookmarks =
-icon:browse =
-icon:cancel =
-icon:checked =
-icon:chevron_down =
-icon:chevron_left =
-icon:chevron_right =
-icon:chevron_up =
-icon:close =
-icon:copy =
-icon:document_add =
-icon:document =
-icon:edit =
-icon:exclude =
-icon:export =
-icon:filter =
-icon:fit_height =
-icon:fit_width =
-icon:folder =
-icon:font =
-icon:import =
-icon:language =
-icon:lines =
-icon:list =
-icon:manuscript =
-icon:margin_bottom =
-icon:margin_left =
-icon:margin_right =
-icon:margin_top =
-icon:maximise =
-icon:minimise =
-icon:more_arrow =
-icon:more_vertical =
-icon:noncheckable =
-icon:novel_view =
-icon:open =
-icon:outline =
-icon:panel =
-icon:pin =
-icon:project_copy =
-icon:project_view =
-icon:quote =
-icon:refresh =
-icon:remove =
-icon:revert =
-icon:settings =
-icon:star =
-icon:stats =
-icon:text =
-icon:timer_off =
-icon:timer =
-icon:unchecked =
-icon:view =
+icon:alert_error =
+icon:alert_info =
+icon:alert_question =
+icon:alert_warn =
+icon:cls_archive =
+icon:cls_character =
+icon:cls_custom =
+icon:cls_entity =
+icon:cls_none =
+icon:cls_novel =
+icon:cls_object =
+icon:cls_plot =
+icon:cls_template =
+icon:cls_timeline =
+icon:cls_trash =
+icon:cls_world =
+icon:prj_folder =
+icon:prj_document =
+icon:prj_title =
+icon:prj_chapter =
+icon:prj_scene =
+icon:prj_note =
+icon:fmt_bold =
+icon:fmt_italic =
+icon:fmt_mark =
+icon:fmt_strike =
+icon:fmt_subscript =
+icon:fmt_superscript =
+icon:fmt_underline =
+icon:fmt_toolbar =
+icon:search =
+icon:search_cancel =
+icon:search_case =
+icon:search_loop =
+icon:search_preserve =
+icon:search_project =
+icon:search_regex =
+icon:search_replace =
+icon:search_word =
+icon:bullet-off =
+icon:bullet-on =
+icon:unfold-hide =
+icon:unfold-show =
+icon:sb_project =
+icon:sb_novel =
+icon:sb_search =
+icon:sb_outline =
+icon:sb_build =
+icon:add =
+icon:bookmarks =
+icon:browse =
+icon:cancel =
+icon:checked =
+icon:chevron_down =
+icon:chevron_left =
+icon:chevron_right =
+icon:chevron_up =
+icon:close =
+icon:copy =
+icon:document_add =
+icon:document =
+icon:edit =
+icon:exclude =
+icon:export =
+icon:filter =
+icon:fit_height =
+icon:fit_width =
+icon:folder =
+icon:font =
+icon:import =
+icon:language =
+icon:lines =
+icon:list =
+icon:manuscript =
+icon:margin_bottom =
+icon:margin_left =
+icon:margin_right =
+icon:margin_top =
+icon:maximise =
+icon:minimise =
+icon:more_arrow =
+icon:more_vertical =
+icon:noncheckable =
+icon:open =
+icon:panel =
+icon:pin =
+icon:project_copy =
+icon:quote =
+icon:refresh =
+icon:remove =
+icon:revert =
+icon:settings =
+icon:star =
+icon:stats =
+icon:text =
+icon:timer_off =
+icon:timer =
+icon:unchecked =
+icon:view =
diff --git a/novelwriter/assets/icons/material_rounded_normal.icons b/novelwriter/assets/icons/material_rounded_normal.icons
index f6995c5b9..4dd356dbf 100644
--- a/novelwriter/assets/icons/material_rounded_normal.icons
+++ b/novelwriter/assets/icons/material_rounded_normal.icons
@@ -6,100 +6,102 @@ meta:author = Google Inc
meta:license = Apache 2.0
# Icons
-icon:alert_error =
-icon:alert_info =
-icon:alert_question =
-icon:alert_warn =
-icon:cls_archive =
-icon:cls_character =
-icon:cls_custom =
-icon:cls_entity =
-icon:cls_none =
-icon:cls_novel =
-icon:cls_object =
-icon:cls_plot =
-icon:cls_template =
-icon:cls_timeline =
-icon:cls_trash =
-icon:cls_world =
-icon:prj_folder =
-icon:prj_document =
-icon:prj_title =
-icon:prj_chapter =
-icon:prj_scene =
-icon:prj_note =
-icon:fmt_bold =
-icon:fmt_italic =
-icon:fmt_mark =
-icon:fmt_strike =
-icon:fmt_subscript =
-icon:fmt_superscript =
-icon:fmt_underline =
-icon:fmt_toolbar =
-icon:search =
-icon:search_cancel =
-icon:search_case =
-icon:search_loop =
-icon:search_preserve =
-icon:search_project =
-icon:search_regex =
-icon:search_replace =
-icon:search_word =
-icon:bullet-off =
-icon:bullet-on =
-icon:unfold-hide =
-icon:unfold-show =
-icon:add =
-icon:bookmarks =
-icon:browse =
-icon:cancel =
-icon:checked =
-icon:chevron_down =
-icon:chevron_left =
-icon:chevron_right =
-icon:chevron_up =
-icon:close =
-icon:copy =
-icon:document_add =
-icon:document =
-icon:edit =
-icon:exclude =
-icon:export =
-icon:filter =
-icon:fit_height =
-icon:fit_width =
-icon:folder =
-icon:font =
-icon:import =
-icon:language =
-icon:lines =
-icon:list =
-icon:manuscript =
-icon:margin_bottom =
-icon:margin_left =
-icon:margin_right =
-icon:margin_top =
-icon:maximise =
-icon:minimise =
-icon:more_arrow =
-icon:more_vertical =
-icon:noncheckable =
-icon:novel_view =
-icon:open =
-icon:outline =
-icon:panel =
-icon:pin =
-icon:project_copy =
-icon:project_view =
-icon:quote =
-icon:refresh =
-icon:remove =
-icon:revert =
-icon:settings =
-icon:star =
-icon:stats =
-icon:text =
-icon:timer_off =
-icon:timer =
-icon:unchecked =
-icon:view =
+icon:alert_error =
+icon:alert_info =
+icon:alert_question =
+icon:alert_warn =
+icon:cls_archive =
+icon:cls_character =
+icon:cls_custom =
+icon:cls_entity =
+icon:cls_none =
+icon:cls_novel =
+icon:cls_object =
+icon:cls_plot =
+icon:cls_template =
+icon:cls_timeline =
+icon:cls_trash =
+icon:cls_world =
+icon:prj_folder =
+icon:prj_document =
+icon:prj_title =
+icon:prj_chapter =
+icon:prj_scene =
+icon:prj_note =
+icon:fmt_bold =
+icon:fmt_italic =
+icon:fmt_mark =
+icon:fmt_strike =
+icon:fmt_subscript =
+icon:fmt_superscript =
+icon:fmt_underline =
+icon:fmt_toolbar =
+icon:search =
+icon:search_cancel =
+icon:search_case =
+icon:search_loop =
+icon:search_preserve =
+icon:search_project =
+icon:search_regex =
+icon:search_replace =
+icon:search_word =
+icon:bullet-off =
+icon:bullet-on =
+icon:unfold-hide =
+icon:unfold-show =
+icon:sb_project =
+icon:sb_novel =
+icon:sb_search =
+icon:sb_outline =
+icon:sb_build =
+icon:add =
+icon:bookmarks =
+icon:browse =
+icon:cancel =
+icon:checked =
+icon:chevron_down =
+icon:chevron_left =
+icon:chevron_right =
+icon:chevron_up =
+icon:close =
+icon:copy =
+icon:document_add =
+icon:document =
+icon:edit =
+icon:exclude =
+icon:export =
+icon:filter =
+icon:fit_height =
+icon:fit_width =
+icon:folder =
+icon:font =
+icon:import =
+icon:language =
+icon:lines =
+icon:list =
+icon:manuscript =
+icon:margin_bottom =
+icon:margin_left =
+icon:margin_right =
+icon:margin_top =
+icon:maximise =
+icon:minimise =
+icon:more_arrow =
+icon:more_vertical =
+icon:noncheckable =
+icon:open =
+icon:panel =
+icon:pin =
+icon:project_copy =
+icon:quote =
+icon:refresh =
+icon:remove =
+icon:revert =
+icon:settings =
+icon:star =
+icon:stats =
+icon:text =
+icon:timer_off =
+icon:timer =
+icon:unchecked =
+icon:view =
diff --git a/novelwriter/assets/icons/material_rounded_thin.icons b/novelwriter/assets/icons/material_rounded_thin.icons
index e809255b3..a26a02f0f 100644
--- a/novelwriter/assets/icons/material_rounded_thin.icons
+++ b/novelwriter/assets/icons/material_rounded_thin.icons
@@ -6,100 +6,102 @@ meta:author = Google Inc
meta:license = Apache 2.0
# Icons
-icon:alert_error =
-icon:alert_info =
-icon:alert_question =
-icon:alert_warn =
-icon:cls_archive =
-icon:cls_character =
-icon:cls_custom =
-icon:cls_entity =
-icon:cls_none =
-icon:cls_novel =
-icon:cls_object =
-icon:cls_plot =
-icon:cls_template =
-icon:cls_timeline =
-icon:cls_trash =
-icon:cls_world =
-icon:prj_folder =
-icon:prj_document =
-icon:prj_title =
-icon:prj_chapter =
-icon:prj_scene =
-icon:prj_note =
-icon:fmt_bold =
-icon:fmt_italic =
-icon:fmt_mark =
-icon:fmt_strike =
-icon:fmt_subscript =
-icon:fmt_superscript =
-icon:fmt_underline =
-icon:fmt_toolbar =
-icon:search =
-icon:search_cancel =
-icon:search_case =
-icon:search_loop =
-icon:search_preserve =
-icon:search_project =
-icon:search_regex =
-icon:search_replace =
-icon:search_word =
-icon:bullet-off =
-icon:bullet-on =
-icon:unfold-hide =
-icon:unfold-show =
-icon:add =
-icon:bookmarks =
-icon:browse =
-icon:cancel =
-icon:checked =
-icon:chevron_down =
-icon:chevron_left =
-icon:chevron_right =
-icon:chevron_up =
-icon:close =
-icon:copy =
-icon:document_add =
-icon:document =
-icon:edit =
-icon:exclude =
-icon:export =
-icon:filter =
-icon:fit_height =
-icon:fit_width =
-icon:folder =
-icon:font =
-icon:import =
-icon:language =
-icon:lines =
-icon:list =
-icon:manuscript =
-icon:margin_bottom =
-icon:margin_left =
-icon:margin_right =
-icon:margin_top =
-icon:maximise =
-icon:minimise =
-icon:more_arrow =
-icon:more_vertical =
-icon:noncheckable =
-icon:novel_view =
-icon:open =
-icon:outline =
-icon:panel =
-icon:pin =
-icon:project_copy =
-icon:project_view =
-icon:quote =
-icon:refresh =
-icon:remove =
-icon:revert =
-icon:settings =
-icon:star =
-icon:stats =
-icon:text =
-icon:timer_off =
-icon:timer =
-icon:unchecked =
-icon:view =
+icon:alert_error =
+icon:alert_info =
+icon:alert_question =
+icon:alert_warn =
+icon:cls_archive =
+icon:cls_character =
+icon:cls_custom =
+icon:cls_entity =
+icon:cls_none =
+icon:cls_novel =
+icon:cls_object =
+icon:cls_plot =
+icon:cls_template =
+icon:cls_timeline =
+icon:cls_trash =
+icon:cls_world =
+icon:prj_folder =
+icon:prj_document =
+icon:prj_title =
+icon:prj_chapter =
+icon:prj_scene =
+icon:prj_note =
+icon:fmt_bold =
+icon:fmt_italic =
+icon:fmt_mark =
+icon:fmt_strike =
+icon:fmt_subscript =
+icon:fmt_superscript =
+icon:fmt_underline =
+icon:fmt_toolbar =
+icon:search =
+icon:search_cancel =
+icon:search_case =
+icon:search_loop =
+icon:search_preserve =
+icon:search_project =
+icon:search_regex =
+icon:search_replace =
+icon:search_word =
+icon:bullet-off =
+icon:bullet-on =
+icon:unfold-hide =
+icon:unfold-show =
+icon:sb_project =
+icon:sb_novel =
+icon:sb_search =
+icon:sb_outline =
+icon:sb_build =
+icon:add =
+icon:bookmarks =
+icon:browse =
+icon:cancel =
+icon:checked =
+icon:chevron_down =
+icon:chevron_left =
+icon:chevron_right =
+icon:chevron_up =
+icon:close =
+icon:copy =
+icon:document_add =
+icon:document =
+icon:edit =
+icon:exclude =
+icon:export =
+icon:filter =
+icon:fit_height =
+icon:fit_width =
+icon:folder =
+icon:font =
+icon:import =
+icon:language =
+icon:lines =
+icon:list =
+icon:manuscript =
+icon:margin_bottom =
+icon:margin_left =
+icon:margin_right =
+icon:margin_top =
+icon:maximise =
+icon:minimise =
+icon:more_arrow =
+icon:more_vertical =
+icon:noncheckable =
+icon:open =
+icon:panel =
+icon:pin =
+icon:project_copy =
+icon:quote =
+icon:refresh =
+icon:remove =
+icon:revert =
+icon:settings =
+icon:star =
+icon:stats =
+icon:text =
+icon:timer_off =
+icon:timer =
+icon:unchecked =
+icon:view =
diff --git a/novelwriter/gui/sidebar.py b/novelwriter/gui/sidebar.py
index d42e7a87c..8baaaa48e 100644
--- a/novelwriter/gui/sidebar.py
+++ b/novelwriter/gui/sidebar.py
@@ -140,11 +140,11 @@ def updateTheme(self) -> None:
self.tbStats.setStyleSheet(buttonStyle)
self.tbSettings.setStyleSheet(buttonStyle)
- self.tbProject.setThemeIcon("project_view")
- self.tbNovel.setThemeIcon("novel_view")
- self.tbSearch.setThemeIcon("search")
- self.tbOutline.setThemeIcon("outline")
- self.tbBuild.setThemeIcon("manuscript")
+ self.tbProject.setThemeIcon("sb_project")
+ self.tbNovel.setThemeIcon("sb_novel")
+ self.tbSearch.setThemeIcon("sb_search")
+ self.tbOutline.setThemeIcon("sb_outline")
+ self.tbBuild.setThemeIcon("sb_build")
self.tbDetails.setThemeIcon("list")
self.tbStats.setThemeIcon("stats")
self.tbSettings.setThemeIcon("settings")
diff --git a/utils/icon_themes.py b/utils/icon_themes.py
index 1371debde..01a5bdf64 100644
--- a/utils/icon_themes.py
+++ b/utils/icon_themes.py
@@ -81,6 +81,12 @@
"unfold-hide",
"unfold-show",
+ "sb_project",
+ "sb_novel",
+ "sb_search",
+ "sb_outline",
+ "sb_build",
+
"add",
"bookmarks",
"browse",
@@ -116,13 +122,10 @@
"more_arrow",
"more_vertical",
"noncheckable",
- "novel_view",
"open",
- "outline",
"panel",
"pin",
"project_copy",
- "project_view",
"quote",
"refresh",
"remove",
diff --git a/utils/material_symbols.json b/utils/material_symbols.json
index 7abb89244..09818e651 100644
--- a/utils/material_symbols.json
+++ b/utils/material_symbols.json
@@ -48,6 +48,12 @@
"unfold-hide": "arrow_right",
"unfold-show": "arrow_drop_down",
+ "sb_project": "bookmark_manager",
+ "sb_novel": "book_4_spark",
+ "sb_search": "search",
+ "sb_outline": "summarize",
+ "sb_build": "export_notes",
+
"add": "add",
"bookmarks": "bookmarks",
"browse": "folder_open",
@@ -83,13 +89,10 @@
"more_arrow": "arrow_right",
"more_vertical": "more_vert",
"noncheckable": "indeterminate_check_box",
- "novel_view": "book_4_spark",
"open": "open_in_new",
- "outline": "summarize",
"panel": "dock_to_bottom",
"pin": "keep",
"project_copy": "folder_copy",
- "project_view": "bookmark_manager",
"quote": "format_quote",
"refresh": "refresh",
"remove": "remove",
From 586370188bdf799e524deeb87a676519ed652157 Mon Sep 17 00:00:00 2001
From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com>
Date: Fri, 10 Jan 2025 17:40:16 +0100
Subject: [PATCH 3/6] Add Font Awesome icons
---
novelwriter/assets/icons/font_awesome.icons | 107 +++++++++++++++++++
utils/font_awesome.json | 108 ++++++++++++++++++++
2 files changed, 215 insertions(+)
create mode 100644 novelwriter/assets/icons/font_awesome.icons
create mode 100644 utils/font_awesome.json
diff --git a/novelwriter/assets/icons/font_awesome.icons b/novelwriter/assets/icons/font_awesome.icons
new file mode 100644
index 000000000..5e933ffda
--- /dev/null
+++ b/novelwriter/assets/icons/font_awesome.icons
@@ -0,0 +1,107 @@
+# This file is automatically generated. Do not edit.
+
+# Meta
+meta:name = Font Awesome 6
+meta:author = Fonticons Inc
+meta:license = Font Awesome Free License
+
+# Icons
+icon:alert_error =
+icon:alert_info =
+icon:alert_question =
+icon:alert_warn =
+icon:cls_archive =
+icon:cls_character =
+icon:cls_custom =
+icon:cls_entity =
+icon:cls_none =
+icon:cls_novel =
+icon:cls_object =
+icon:cls_plot =
+icon:cls_template =
+icon:cls_timeline =
+icon:cls_trash =
+icon:cls_world =
+icon:prj_folder =
+icon:prj_document =
+icon:prj_title =
+icon:prj_chapter =
+icon:prj_scene =
+icon:prj_note =
+icon:fmt_bold =
+icon:fmt_italic =
+icon:fmt_mark =
+icon:fmt_strike =
+icon:fmt_subscript =
+icon:fmt_superscript =
+icon:fmt_underline =
+icon:fmt_toolbar =
+icon:search =
+icon:search_cancel =
+icon:search_case =
+icon:search_loop =
+icon:search_preserve =
+icon:search_project =
+icon:search_regex =
+icon:search_replace =
+icon:search_word =
+icon:bullet-off =
+icon:bullet-on =
+icon:unfold-hide =
+icon:unfold-show =
+icon:sb_project =
+icon:sb_novel =
+icon:sb_search =
+icon:sb_outline =
+icon:sb_build =
+icon:add =
+icon:bookmarks =
+icon:browse =
+icon:cancel =
+icon:checked =
+icon:chevron_down =
+icon:chevron_left =
+icon:chevron_right =
+icon:chevron_up =
+icon:close =
+icon:copy =
+icon:document_add =
+icon:document =
+icon:edit =
+icon:exclude =
+icon:export =
+icon:filter =
+icon:fit_height =
+icon:fit_width =
+icon:folder =
+icon:font =
+icon:import =
+icon:language =
+icon:lines =
+icon:list =
+icon:manuscript =
+icon:margin_bottom =
+icon:margin_left =
+icon:margin_right =
+icon:margin_top =
+icon:maximise =
+icon:minimise =
+icon:more_arrow =
+icon:more_vertical =
+icon:noncheckable =
+icon:open =
+icon:panel =
+icon:pin =
+icon:project_copy =
+icon:quote =
+icon:refresh =
+icon:remove =
+icon:revert =
+icon:settings =
+icon:star =
+icon:stats =
+icon:text =
+icon:timer_off =
+icon:timer =
+icon:unchecked =
+icon:view =
diff --git a/utils/font_awesome.json b/utils/font_awesome.json
new file mode 100644
index 000000000..e1c60d55d
--- /dev/null
+++ b/utils/font_awesome.json
@@ -0,0 +1,108 @@
+{
+ "alert_error": "circle-exclamation",
+ "alert_info": "circle-info",
+ "alert_question": "circle-question",
+ "alert_warn": "triangle-exclamation",
+
+ "cls_archive": "box-archive",
+ "cls_character": "user-group",
+ "cls_custom": "tag",
+ "cls_entity": "building",
+ "cls_none": "notdef",
+ "cls_novel": "book",
+ "cls_object": "key",
+ "cls_plot": "puzzle-piece",
+ "cls_template": "folder-plus",
+ "cls_timeline": "hourglass-end",
+ "cls_trash": "trash-can",
+ "cls_world": "earth-africa",
+
+ "prj_folder": "folder",
+ "prj_document": "file-lines",
+ "prj_title": "file-lines",
+ "prj_chapter": "file-lines",
+ "prj_scene": "file-lines",
+ "prj_note": "note-sticky",
+
+ "fmt_bold": "bold",
+ "fmt_italic": "italic",
+ "fmt_mark": "highlighter",
+ "fmt_strike": "strikethrough",
+ "fmt_subscript": "subscript",
+ "fmt_superscript": "superscript",
+ "fmt_underline": "underline",
+ "fmt_toolbar": "square",
+
+ "search": "magnifying-glass",
+ "search_cancel": "xmark",
+ "search_case": "font",
+ "search_loop": "repeat",
+ "search_preserve": "text-height",
+ "search_project": "file-arrow-down",
+ "search_regex": "asterisk",
+ "search_replace": "magnifying-glass-arrow-right",
+ "search_word": "text-width",
+
+ "bullet-off": "circle:regular",
+ "bullet-on": "circle:solid",
+ "unfold-hide": "caret-right",
+ "unfold-show": "caret-down",
+
+ "sb_project": "pen-to-square",
+ "sb_novel": "book-open",
+ "sb_search": "magnifying-glass",
+ "sb_outline": "table-list",
+ "sb_build": "up-right-from-square",
+
+ "add": "plus",
+ "bookmarks": "bookmark",
+ "browse": "folder-open",
+ "cancel": "ban",
+ "checked": "square-check",
+ "chevron_down": "chevron-down",
+ "chevron_left": "chevron-left",
+ "chevron_right": "chevron-right",
+ "chevron_up": "chevron-up",
+ "close": "xmark",
+ "copy": "clone",
+ "document_add": "file-circle-plus",
+ "document": "file",
+ "edit": "pen",
+ "exclude": "ban",
+ "export": "file-export",
+ "filter": "filter",
+ "fit_height": "arrows-up-down",
+ "fit_width": "arrows-left-right",
+ "folder": "folder",
+ "font": "font",
+ "import": "file-import",
+ "language": "spell-check",
+ "lines": "align-left",
+ "list": "list",
+ "manuscript": "up-right-from-square",
+ "margin_bottom": "arrow-down",
+ "margin_left": "arrow-left",
+ "margin_right": "arrow-right",
+ "margin_top": "arrow-up",
+ "maximise": "maximize",
+ "minimise": "minimize",
+ "more_arrow": "caret-right",
+ "more_vertical": "ellipsis-vertical",
+ "noncheckable": "square-minus",
+ "open": "file-arrow-up",
+ "panel": "table-list",
+ "pin": "thumbtack",
+ "project_copy": "copy",
+ "quote": "quote-right",
+ "refresh": "arrow-rotate-right",
+ "remove": "minus",
+ "revert": "arrow-rotate-left",
+ "settings": "gear",
+ "star": "star",
+ "stats": "chart-simple",
+ "text": "file-lines",
+ "timer_off": "pause",
+ "timer": "clock",
+ "unchecked": "square-xmark",
+ "view": "minus"
+}
From fbcf185c13996b23de8a45f9451eb3a1befc2a5c Mon Sep 17 00:00:00 2001
From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com>
Date: Fri, 10 Jan 2025 18:49:23 +0100
Subject: [PATCH 4/6] Add Remix Icon themes
---
novelwriter/assets/icons/remix_filled.icons | 106 ++++++++++++++++++
novelwriter/assets/icons/remix_outline.icons | 106 ++++++++++++++++++
novelwriter/tools/manusbuild.py | 2 +-
novelwriter/tools/manuscript.py | 2 +-
pkgutils.py | 14 ++-
utils/icon_themes.py | 64 ++++++++---
utils/remix.json | 108 +++++++++++++++++++
7 files changed, 387 insertions(+), 15 deletions(-)
create mode 100644 novelwriter/assets/icons/remix_filled.icons
create mode 100644 novelwriter/assets/icons/remix_outline.icons
create mode 100644 utils/remix.json
diff --git a/novelwriter/assets/icons/remix_filled.icons b/novelwriter/assets/icons/remix_filled.icons
new file mode 100644
index 000000000..f811c500a
--- /dev/null
+++ b/novelwriter/assets/icons/remix_filled.icons
@@ -0,0 +1,106 @@
+# This file is automatically generated. Do not edit.
+
+# Meta
+meta:name = Remix Icon - Filled
+meta:author = Remix Icon
+meta:license = Apache 2.0
+
+# Icons
+icon:alert_error =
+icon:alert_info =
+icon:alert_question =
+icon:alert_warn =
+icon:cls_archive =
+icon:cls_character =
+icon:cls_custom =
+icon:cls_entity =
+icon:cls_none =
+icon:cls_novel =
+icon:cls_object =
+icon:cls_plot =
+icon:cls_template =
+icon:cls_timeline =
+icon:cls_trash =
+icon:cls_world =
+icon:prj_folder =
+icon:prj_document =
+icon:prj_title =
+icon:prj_chapter =
+icon:prj_scene =
+icon:prj_note =
+icon:fmt_bold =
+icon:fmt_italic =
+icon:fmt_mark =
+icon:fmt_strike =
+icon:fmt_subscript =
+icon:fmt_superscript =
+icon:fmt_underline =
+icon:fmt_toolbar =
+icon:search =
+icon:search_cancel =
+icon:search_case =
+icon:search_loop =
+icon:search_preserve =
+icon:search_project =
+icon:search_regex =
+icon:search_replace =
+icon:search_word =
+icon:bullet-off =
+icon:bullet-on =
+icon:unfold-hide =
+icon:unfold-show =
+icon:sb_build =
+icon:sb_novel =
+icon:sb_outline =
+icon:sb_project =
+icon:sb_search =
+icon:add =
+icon:bookmarks =
+icon:browse =
+icon:build_settings =
+icon:cancel =
+icon:checked =
+icon:chevron_down =
+icon:chevron_left =
+icon:chevron_right =
+icon:chevron_up =
+icon:close =
+icon:copy =
+icon:document_add =
+icon:document =
+icon:edit =
+icon:exclude =
+icon:export =
+icon:filter =
+icon:fit_height =
+icon:fit_width =
+icon:folder =
+icon:font =
+icon:import =
+icon:language =
+icon:lines =
+icon:list =
+icon:margin_bottom =
+icon:margin_left =
+icon:margin_right =
+icon:margin_top =
+icon:maximise =
+icon:minimise =
+icon:more_arrow =
+icon:more_vertical =
+icon:noncheckable =
+icon:open =
+icon:panel =
+icon:pin =
+icon:quote =
+icon:refresh =
+icon:remove =
+icon:revert =
+icon:settings =
+icon:star =
+icon:stats =
+icon:text =
+icon:timer_off =
+icon:timer =
+icon:unchecked =
+icon:view =
diff --git a/novelwriter/assets/icons/remix_outline.icons b/novelwriter/assets/icons/remix_outline.icons
new file mode 100644
index 000000000..ecf7e9abc
--- /dev/null
+++ b/novelwriter/assets/icons/remix_outline.icons
@@ -0,0 +1,106 @@
+# This file is automatically generated. Do not edit.
+
+# Meta
+meta:name = Remix Icon - Outline
+meta:author = Remix Icon
+meta:license = Apache 2.0
+
+# Icons
+icon:alert_error =
+icon:alert_info =
+icon:alert_question =
+icon:alert_warn =
+icon:cls_archive =
+icon:cls_character =
+icon:cls_custom =
+icon:cls_entity =
+icon:cls_none =
+icon:cls_novel =
+icon:cls_object =
+icon:cls_plot =
+icon:cls_template =
+icon:cls_timeline =
+icon:cls_trash =
+icon:cls_world =
+icon:prj_folder =
+icon:prj_document =
+icon:prj_title =
+icon:prj_chapter =
+icon:prj_scene =
+icon:prj_note =
+icon:fmt_bold =
+icon:fmt_italic =
+icon:fmt_mark =
+icon:fmt_strike =
+icon:fmt_subscript =
+icon:fmt_superscript =
+icon:fmt_underline =
+icon:fmt_toolbar =
+icon:search =
+icon:search_cancel =
+icon:search_case =
+icon:search_loop =
+icon:search_preserve =
+icon:search_project =
+icon:search_regex =
+icon:search_replace =
+icon:search_word =
+icon:bullet-off =
+icon:bullet-on =
+icon:unfold-hide =
+icon:unfold-show =
+icon:sb_build =
+icon:sb_novel =
+icon:sb_outline =
+icon:sb_project =
+icon:sb_search =
+icon:add =
+icon:bookmarks =
+icon:browse =
+icon:build_settings =
+icon:cancel =
+icon:checked =
+icon:chevron_down =
+icon:chevron_left =
+icon:chevron_right =
+icon:chevron_up =
+icon:close =
+icon:copy =
+icon:document_add =
+icon:document =
+icon:edit =
+icon:exclude =
+icon:export =
+icon:filter =
+icon:fit_height =
+icon:fit_width =
+icon:folder =
+icon:font =
+icon:import =
+icon:language =
+icon:lines =
+icon:list =
+icon:margin_bottom =
+icon:margin_left =
+icon:margin_right =
+icon:margin_top =
+icon:maximise =
+icon:minimise =
+icon:more_arrow =
+icon:more_vertical =
+icon:noncheckable =
+icon:open =
+icon:panel =
+icon:pin =
+icon:quote =
+icon:refresh =
+icon:remove =
+icon:revert =
+icon:settings =
+icon:star =
+icon:stats =
+icon:text =
+icon:timer_off =
+icon:timer =
+icon:unchecked =
+icon:view =
diff --git a/novelwriter/tools/manusbuild.py b/novelwriter/tools/manusbuild.py
index 4c90aa73c..b636ac3c9 100644
--- a/novelwriter/tools/manusbuild.py
+++ b/novelwriter/tools/manusbuild.py
@@ -189,7 +189,7 @@ def __init__(self, parent: QWidget, build: BuildSettings) -> None:
self.buttonBox.addButton(self.btnOpen, QtRoleAction)
self.btnBuild = QPushButton(
- SHARED.theme.getIcon("manuscript", "blue"), self.tr("&Build"), self
+ SHARED.theme.getIcon("sb_build", "blue"), self.tr("&Build"), self
)
self.btnBuild.setIconSize(bSz)
self.btnBuild.setAutoDefault(True)
diff --git a/novelwriter/tools/manuscript.py b/novelwriter/tools/manuscript.py
index c0ea46f50..07501af1d 100644
--- a/novelwriter/tools/manuscript.py
+++ b/novelwriter/tools/manuscript.py
@@ -490,7 +490,7 @@ def _updateBuildsList(self) -> None:
for key, name in self._builds.builds():
bItem = QListWidgetItem()
bItem.setText(name)
- bItem.setIcon(SHARED.theme.getIcon("manuscript", "blue"))
+ bItem.setIcon(SHARED.theme.getIcon("build_settings", "blue"))
bItem.setData(self.D_KEY, key)
self.buildList.addItem(bItem)
self._buildMap[key] = bItem
diff --git a/pkgutils.py b/pkgutils.py
index aa4ddad6c..8e0d5cbf5 100755
--- a/pkgutils.py
+++ b/pkgutils.py
@@ -35,7 +35,7 @@
from pathlib import Path
-from utils.icon_themes import processFontAwesome, processMaterialIcons
+from utils.icon_themes import processFontAwesome, processMaterialIcons, processRemix
CURR_DIR = Path(__file__).parent
SETUP_DIR = CURR_DIR / "setup"
@@ -391,6 +391,18 @@ def buildIconTheme(args: argparse.Namespace) -> None:
},
})
+ if style in ("all", "remix"):
+ processRemix(workDir, iconsDir, {
+ "remix_outline": {
+ "name": "Remix Icon - Outline",
+ "filled": False,
+ },
+ "remix_filled": {
+ "name": "Remix Icon - Filled",
+ "filled": True,
+ },
+ })
+
print("Done")
print("")
diff --git a/utils/icon_themes.py b/utils/icon_themes.py
index 01a5bdf64..53d974d5b 100644
--- a/utils/icon_themes.py
+++ b/utils/icon_themes.py
@@ -27,10 +27,7 @@
from xml.etree import ElementTree as ET
UTILS = Path(__file__).parent
-
ET.register_namespace("", "http://www.w3.org/2000/svg")
-MATERIAL_REPO = "https://github.com/google/material-design-icons.git"
-FONT_AWESOME_REPO = "https://github.com/FortAwesome/Font-Awesome.git"
ICONS = [
"alert_error",
"alert_info",
@@ -81,15 +78,16 @@
"unfold-hide",
"unfold-show",
- "sb_project",
+ "sb_build",
"sb_novel",
- "sb_search",
"sb_outline",
- "sb_build",
+ "sb_project",
+ "sb_search",
"add",
"bookmarks",
"browse",
+ "build_settings",
"cancel",
"checked",
"chevron_down",
@@ -112,7 +110,6 @@
"language",
"lines",
"list",
- "manuscript",
"margin_bottom",
"margin_left",
"margin_right",
@@ -194,7 +191,7 @@ def _cloneRepo(repoPath: Path, repoUrl: str) -> None:
def processMaterialIcons(workDir: Path, iconsDir: Path, jobs: dict) -> None:
"""Process material icons of a given spec and write output file."""
srcRepo = workDir / "material-design-icons"
- _cloneRepo(srcRepo, MATERIAL_REPO)
+ _cloneRepo(srcRepo, "https://github.com/google/material-design-icons.git")
for file, job in jobs.items():
name: str = job["name"]
@@ -211,10 +208,10 @@ def processMaterialIcons(workDir: Path, iconsDir: Path, jobs: dict) -> None:
iconSrc = srcRepo / "symbols" / "web"
for key, icon in _loadMap("material_symbols").items():
if kind:
- fileNmae = f"{icon}_{kind}_24px.svg"
+ fileName = f"{icon}_{kind}_24px.svg"
else:
- fileNmae = f"{icon}_24px.svg"
- iconFile = iconSrc / icon / f"materialsymbols{style}" / fileNmae
+ fileName = f"{icon}_24px.svg"
+ iconFile = iconSrc / icon / f"materialsymbols{style}" / fileName
if iconFile.is_file():
icons[key] = ET.fromstring(iconFile.read_text(encoding="utf-8"))
else:
@@ -231,7 +228,7 @@ def processMaterialIcons(workDir: Path, iconsDir: Path, jobs: dict) -> None:
def processFontAwesome(workDir: Path, iconsDir: Path, jobs: dict) -> None:
"""Process Font Awesome icons of a given spec and write output file."""
srcRepo = workDir / "Font-Awesome"
- _cloneRepo(srcRepo, FONT_AWESOME_REPO)
+ _cloneRepo(srcRepo, "https://github.com/FortAwesome/Font-Awesome.git")
for file, job in jobs.items():
name: str = job["name"]
@@ -271,3 +268,46 @@ def processFontAwesome(workDir: Path, iconsDir: Path, jobs: dict) -> None:
print("")
return
+
+
+def processRemix(workDir: Path, iconsDir: Path, jobs: dict) -> None:
+ """Process Remix icons of a given spec and write output file."""
+ srcRepo = workDir / "RemixIcon"
+ _cloneRepo(srcRepo, "https://github.com/Remix-Design/RemixIcon.git")
+
+ for file, job in jobs.items():
+ name: str = job["name"]
+ style = "fill" if job["filled"] else "line"
+
+ print(f"Processing: {name}")
+
+ icons: dict[str, ET.Element] = {}
+ iconSrc = srcRepo / "icons"
+ iconGroups = [x for x in iconSrc.iterdir() if x.is_dir()]
+ for key, icon in _loadMap("remix").items():
+ if icon.endswith(("-line", "-fill")):
+ fileName = f"{icon}.svg"
+ else:
+ fileName = f"{icon}-{style}.svg"
+ for group in iconGroups:
+ iconFile = group / fileName
+ if iconFile.is_file():
+ break
+ else:
+ fileName = f"{icon}.svg"
+ for group in iconGroups:
+ iconFile = group / fileName
+ if iconFile.is_file():
+ break
+ else:
+ print(f"Not Found: {fileName}")
+ continue
+
+ icons[key] = ET.fromstring(iconFile.read_text(encoding="utf-8"))
+
+ target = iconsDir / f"{file}.icons"
+ _writeThemeFile(target, name, "Remix Icon", "Apache 2.0", icons)
+
+ print("")
+
+ return
diff --git a/utils/remix.json b/utils/remix.json
new file mode 100644
index 000000000..f62a9ee61
--- /dev/null
+++ b/utils/remix.json
@@ -0,0 +1,108 @@
+{
+ "alert_error": "error-warning",
+ "alert_info": "information",
+ "alert_question": "question",
+ "alert_warn": "alarm-warning",
+
+ "cls_archive": "archive",
+ "cls_character": "group",
+ "cls_custom": "price-tag-3",
+ "cls_entity": "building",
+ "cls_none": "checkbox-blank",
+ "cls_novel": "git-repository",
+ "cls_object": "key-2",
+ "cls_plot": "puzzle-2",
+ "cls_template": "folder-add",
+ "cls_timeline": "hourglass",
+ "cls_trash": "delete-bin",
+ "cls_world": "earth",
+
+ "prj_folder": "folder-6",
+ "prj_document": "file-text",
+ "prj_title": "file-text",
+ "prj_chapter": "file-text",
+ "prj_scene": "file-text",
+ "prj_note": "file-4",
+
+ "fmt_bold": "bold",
+ "fmt_italic": "italic",
+ "fmt_mark": "mark-pen",
+ "fmt_strike": "strikethrough",
+ "fmt_subscript": "subscript",
+ "fmt_superscript": "superscript",
+ "fmt_underline": "underline",
+ "fmt_toolbar": "font-color",
+
+ "search": "search-line",
+ "search_cancel": "close",
+ "search_case": "font-size",
+ "search_loop": "loop-right",
+ "search_preserve": "font-size-2",
+ "search_project": "file-search",
+ "search_regex": "asterisk",
+ "search_replace": "find-replace-line",
+ "search_word": "space",
+
+ "bullet-off": "checkbox-blank-circle-line",
+ "bullet-on": "checkbox-blank-circle-fill",
+ "unfold-hide": "arrow-right-s-fill",
+ "unfold-show": "arrow-down-s-fill",
+
+ "sb_build": "stack",
+ "sb_novel": "booklet",
+ "sb_outline": "table-view",
+ "sb_project": "file-edit",
+ "sb_search": "file-search",
+
+ "add": "add",
+ "bookmarks": "bookmark",
+ "browse": "folder-2",
+ "build_settings": "file-settings",
+ "cancel": "prohibited-2",
+ "checked": "checkbox",
+ "chevron_down": "arrow-down-s-line",
+ "chevron_left": "arrow-left-s-line",
+ "chevron_right": "arrow-right-s-line",
+ "chevron_up": "arrow-up-s-line",
+ "close": "close-large",
+ "copy": "file-copy",
+ "document_add": "file-add",
+ "document": "file-text",
+ "edit": "edit",
+ "exclude": "close-circle",
+ "export": "export",
+ "filter": "filter-2",
+ "fit_height": "expand-height-line",
+ "fit_width": "expand-width-line",
+ "folder": "folder-6",
+ "font": "font-sans",
+ "import": "import",
+ "language": "translate-2",
+ "lines": "menu-2",
+ "list": "list-unordered",
+ "margin_bottom": "skip-down-line",
+ "margin_left": "skip-left-line",
+ "margin_right": "skip-right-line",
+ "margin_top": "skip-up-line",
+ "maximise": "fullscreen",
+ "minimise": "fullscreen-exit",
+ "more_arrow": "arrow-right-s-fill",
+ "more_vertical": "more-2",
+ "noncheckable": "checkbox-indeterminate",
+ "open": "file-upload",
+ "panel": "layout-bottom",
+ "pin": "pushpin",
+ "project_copy": "",
+ "quote": "double-quotes-l",
+ "refresh": "refresh-line",
+ "remove": "subtract",
+ "revert": "reset-left",
+ "settings": "settings-2",
+ "star": "star-fill",
+ "stats": "numbers",
+ "text": "file-text",
+ "timer_off": "pause",
+ "timer": "timer",
+ "unchecked": "checkbox-blank",
+ "view": "eye-fill"
+}
From 22fe8f1d129e3e54e654ebd1c18ec0b293e2658c Mon Sep 17 00:00:00 2001
From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com>
Date: Fri, 10 Jan 2025 18:50:19 +0100
Subject: [PATCH 5/6] Update other themes with renamed icon keys
---
novelwriter/assets/icons/font_awesome.icons | 8 ++++----
novelwriter/assets/icons/material_filled_bold.icons | 8 ++++----
novelwriter/assets/icons/material_filled_normal.icons | 8 ++++----
novelwriter/assets/icons/material_filled_thin.icons | 8 ++++----
novelwriter/assets/icons/material_rounded_bold.icons | 8 ++++----
novelwriter/assets/icons/material_rounded_normal.icons | 8 ++++----
novelwriter/assets/icons/material_rounded_thin.icons | 8 ++++----
utils/font_awesome.json | 8 ++++----
utils/material_symbols.json | 8 ++++----
9 files changed, 36 insertions(+), 36 deletions(-)
diff --git a/novelwriter/assets/icons/font_awesome.icons b/novelwriter/assets/icons/font_awesome.icons
index 5e933ffda..847cba7d3 100644
--- a/novelwriter/assets/icons/font_awesome.icons
+++ b/novelwriter/assets/icons/font_awesome.icons
@@ -49,14 +49,15 @@ icon:bullet-off =
icon:unfold-hide =
icon:unfold-show =
-icon:sb_project =
+icon:sb_build =
icon:sb_novel =
-icon:sb_search =
icon:sb_outline =
-icon:sb_build =
+icon:sb_project =
+icon:sb_search =
icon:add =
icon:bookmarks =
icon:browse =
+icon:build_settings =
icon:cancel =
icon:checked =
icon:chevron_down =
@@ -79,7 +80,6 @@ icon:import =
icon:lines =
icon:list =
-icon:manuscript =
icon:margin_bottom =
icon:margin_left =
icon:margin_right =
diff --git a/novelwriter/assets/icons/material_filled_bold.icons b/novelwriter/assets/icons/material_filled_bold.icons
index 37c790471..0fb078668 100644
--- a/novelwriter/assets/icons/material_filled_bold.icons
+++ b/novelwriter/assets/icons/material_filled_bold.icons
@@ -49,14 +49,15 @@ icon:bullet-off =
icon:unfold-hide =
icon:unfold-show =
-icon:sb_project =
+icon:sb_build =
icon:sb_novel =
-icon:sb_search =
icon:sb_outline =
-icon:sb_build =
+icon:sb_project =
+icon:sb_search =
icon:add =
icon:bookmarks =
icon:browse =
+icon:build_settings =
icon:cancel =
icon:checked =
icon:chevron_down =
@@ -79,7 +80,6 @@ icon:import =
icon:lines =
icon:list =
-icon:manuscript =
icon:margin_bottom =
icon:margin_left =
icon:margin_right =
diff --git a/novelwriter/assets/icons/material_filled_normal.icons b/novelwriter/assets/icons/material_filled_normal.icons
index 155b0507d..2c97b6236 100644
--- a/novelwriter/assets/icons/material_filled_normal.icons
+++ b/novelwriter/assets/icons/material_filled_normal.icons
@@ -49,14 +49,15 @@ icon:bullet-off =
icon:unfold-hide =
icon:unfold-show =
-icon:sb_project =
+icon:sb_build =
icon:sb_novel =
-icon:sb_search =
icon:sb_outline =
-icon:sb_build =
+icon:sb_project =
+icon:sb_search =
icon:add =
icon:bookmarks =
icon:browse =
+icon:build_settings =
icon:cancel =
icon:checked =
icon:chevron_down =
@@ -79,7 +80,6 @@ icon:import =
icon:lines =
icon:list =
-icon:manuscript =
icon:margin_bottom =
icon:margin_left =
icon:margin_right =
diff --git a/novelwriter/assets/icons/material_filled_thin.icons b/novelwriter/assets/icons/material_filled_thin.icons
index a04942fdc..bcd4ef974 100644
--- a/novelwriter/assets/icons/material_filled_thin.icons
+++ b/novelwriter/assets/icons/material_filled_thin.icons
@@ -49,14 +49,15 @@ icon:bullet-off =
icon:unfold-hide =
icon:unfold-show =
-icon:sb_project =
+icon:sb_build =
icon:sb_novel =
-icon:sb_search =
icon:sb_outline =
-icon:sb_build =
+icon:sb_project =
+icon:sb_search =
icon:add =
icon:bookmarks =
icon:browse =
+icon:build_settings =
icon:cancel =
icon:checked =
icon:chevron_down =
@@ -79,7 +80,6 @@ icon:import =
icon:lines =
icon:list =
-icon:manuscript =
icon:margin_bottom =
icon:margin_left =
icon:margin_right =
diff --git a/novelwriter/assets/icons/material_rounded_bold.icons b/novelwriter/assets/icons/material_rounded_bold.icons
index 71602cb7f..6b7eb336f 100644
--- a/novelwriter/assets/icons/material_rounded_bold.icons
+++ b/novelwriter/assets/icons/material_rounded_bold.icons
@@ -49,14 +49,15 @@ icon:bullet-off =
icon:unfold-hide =
icon:unfold-show =
-icon:sb_project =
+icon:sb_build =
icon:sb_novel =
-icon:sb_search =
icon:sb_outline =
-icon:sb_build =
+icon:sb_project =
+icon:sb_search =
icon:add =
icon:bookmarks =
icon:browse =
+icon:build_settings =
icon:cancel =
icon:checked =
icon:chevron_down =
@@ -79,7 +80,6 @@ icon:import =
icon:lines =
icon:list =
-icon:manuscript =
icon:margin_bottom =
icon:margin_left =
icon:margin_right =
diff --git a/novelwriter/assets/icons/material_rounded_normal.icons b/novelwriter/assets/icons/material_rounded_normal.icons
index 4dd356dbf..945a8c6ba 100644
--- a/novelwriter/assets/icons/material_rounded_normal.icons
+++ b/novelwriter/assets/icons/material_rounded_normal.icons
@@ -49,14 +49,15 @@ icon:bullet-off =
icon:unfold-hide =
icon:unfold-show =
-icon:sb_project =
+icon:sb_build =
icon:sb_novel =
-icon:sb_search =
icon:sb_outline =
-icon:sb_build =
+icon:sb_project =
+icon:sb_search =
icon:add =
icon:bookmarks =
icon:browse =
+icon:build_settings =
icon:cancel =
icon:checked =
icon:chevron_down =
@@ -79,7 +80,6 @@ icon:import =
icon:lines =
icon:list =
-icon:manuscript =
icon:margin_bottom =
icon:margin_left =
icon:margin_right =
diff --git a/novelwriter/assets/icons/material_rounded_thin.icons b/novelwriter/assets/icons/material_rounded_thin.icons
index a26a02f0f..cb6f05b5a 100644
--- a/novelwriter/assets/icons/material_rounded_thin.icons
+++ b/novelwriter/assets/icons/material_rounded_thin.icons
@@ -49,14 +49,15 @@ icon:bullet-off =
icon:unfold-hide =
icon:unfold-show =
-icon:sb_project =
+icon:sb_build =
icon:sb_novel =
-icon:sb_search =
icon:sb_outline =
-icon:sb_build =
+icon:sb_project =
+icon:sb_search =
icon:add =
icon:bookmarks =
icon:browse =
+icon:build_settings =
icon:cancel =
icon:checked =
icon:chevron_down =
@@ -79,7 +80,6 @@ icon:import =
icon:lines =
icon:list =
-icon:manuscript =
icon:margin_bottom =
icon:margin_left =
icon:margin_right =
diff --git a/utils/font_awesome.json b/utils/font_awesome.json
index e1c60d55d..d33c95a6f 100644
--- a/utils/font_awesome.json
+++ b/utils/font_awesome.json
@@ -48,15 +48,16 @@
"unfold-hide": "caret-right",
"unfold-show": "caret-down",
- "sb_project": "pen-to-square",
+ "sb_build": "up-right-from-square",
"sb_novel": "book-open",
- "sb_search": "magnifying-glass",
"sb_outline": "table-list",
- "sb_build": "up-right-from-square",
+ "sb_project": "pen-to-square",
+ "sb_search": "magnifying-glass",
"add": "plus",
"bookmarks": "bookmark",
"browse": "folder-open",
+ "build_settings": "up-right-from-square",
"cancel": "ban",
"checked": "square-check",
"chevron_down": "chevron-down",
@@ -79,7 +80,6 @@
"language": "spell-check",
"lines": "align-left",
"list": "list",
- "manuscript": "up-right-from-square",
"margin_bottom": "arrow-down",
"margin_left": "arrow-left",
"margin_right": "arrow-right",
diff --git a/utils/material_symbols.json b/utils/material_symbols.json
index 09818e651..6dbc752c6 100644
--- a/utils/material_symbols.json
+++ b/utils/material_symbols.json
@@ -48,15 +48,16 @@
"unfold-hide": "arrow_right",
"unfold-show": "arrow_drop_down",
- "sb_project": "bookmark_manager",
+ "sb_build": "export_notes",
"sb_novel": "book_4_spark",
- "sb_search": "search",
"sb_outline": "summarize",
- "sb_build": "export_notes",
+ "sb_project": "bookmark_manager",
+ "sb_search": "search",
"add": "add",
"bookmarks": "bookmarks",
"browse": "folder_open",
+ "build_settings": "export_notes",
"cancel": "cancel",
"checked": "check_box",
"chevron_down": "keyboard_arrow_down",
@@ -79,7 +80,6 @@
"language": "translate",
"lines": "reorder",
"list": "format_list_bulleted",
- "manuscript": "export_notes",
"margin_bottom": "vertical_align_bottom",
"margin_left": "keyboard_tab_rtl",
"margin_right": "keyboard_tab",
From 1e8b33a74f84a22410dfbab735a9fa734e816093 Mon Sep 17 00:00:00 2001
From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com>
Date: Fri, 10 Jan 2025 19:04:40 +0100
Subject: [PATCH 6/6] Add credits and license info
---
CREDITS.md | 2 ++
novelwriter/assets/text/credits_en.htm | 2 ++
setup/debian/copyright | 23 +++++++++++++++++++++++
setup/iss_license.txt | 10 ++++++++++
utils/icon_themes.py | 2 +-
5 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/CREDITS.md b/CREDITS.md
index ef2b2224b..51c45f6c7 100644
--- a/CREDITS.md
+++ b/CREDITS.md
@@ -55,6 +55,8 @@ The following libraries are dependencies of novelWriter:
Some of the assets bundled with novelWriter were adapted from the following sources:
* **Material Symbols** icons by Google Inc (Apache 2.0)
+* **Remix** icons by RemixIcon (Apache 2.0)
+* **Font Awesome** icons by Fonticons Inc (CC BY 4.0)
* **Tomorrow** syntax themes by Chris Kempson (MIT License)
* **Owl** syntax themes by Sarah Drasner (MIT License)
* **Solarized** themes by Ethan Schoonover (MIT License)
diff --git a/novelwriter/assets/text/credits_en.htm b/novelwriter/assets/text/credits_en.htm
index aa90ae45d..30e6b9e09 100644
--- a/novelwriter/assets/text/credits_en.htm
+++ b/novelwriter/assets/text/credits_en.htm
@@ -66,6 +66,8 @@
Assets
Material Symbols icons by Google Inc (Apache 2.0)
+ Remix icons by RemixIcon (Apache 2.0)
+ Font Awesome icons by Fonticons Inc (CC BY 4.0)
Tomorrow syntax themes by Chris Kempson (MIT License)
Owl syntax themes by Sarah Drasner (MIT License)
Solarized themes by Ethan Schoonover (MIT License)
diff --git a/setup/debian/copyright b/setup/debian/copyright
index 2b2a3300b..e28186b05 100644
--- a/setup/debian/copyright
+++ b/setup/debian/copyright
@@ -33,3 +33,26 @@ License: Apache-2.0
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+
+Files: novelwriter/assets/icons/remix_*
+Copyright: RemixIcon
+License: Apache-2.0
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ .
+ http://www.apache.org/licenses/LICENSE-2.0
+ .
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+Files: novelwriter/assets/icons/font_awesome.*
+Copyright: Fonticons Inc
+License: CC-BY-4.0
+ This work is licensed under Creative Commons Attribution 4.0
+ International. To view a copy of this license, visit
+ .
+ https://creativecommons.org/licenses/by/4.0/
diff --git a/setup/iss_license.txt b/setup/iss_license.txt
index 63726dba2..068dbc70e 100644
--- a/setup/iss_license.txt
+++ b/setup/iss_license.txt
@@ -42,3 +42,13 @@ Material Symbols
Copyright: Google Inc
Website:
License: Apache 2.0
+
+Remix Icon
+Copyright: Remix Icon
+Website:
+License: Apache 2.0
+
+Font Awesome
+Copyright: Fonticons Inc
+Website:
+License: CC BY 4.0
diff --git a/utils/icon_themes.py b/utils/icon_themes.py
index 53d974d5b..8b9b52492 100644
--- a/utils/icon_themes.py
+++ b/utils/icon_themes.py
@@ -263,7 +263,7 @@ def processFontAwesome(workDir: Path, iconsDir: Path, jobs: dict) -> None:
continue
target = iconsDir / f"{file}.icons"
- _writeThemeFile(target, name, "Fonticons Inc", "Font Awesome Free License", icons)
+ _writeThemeFile(target, name, "Fonticons Inc", "CC BY 4.0", icons)
print("")