From ff3cae9db4ce40bdcc148a176f1ea01a2c1f2da7 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Tue, 9 Apr 2024 22:39:46 +0200 Subject: [PATCH] Add status icon shape to project XML --- novelwriter/core/project.py | 22 ++++++++++++---------- novelwriter/core/projectxml.py | 7 +++++-- novelwriter/core/status.py | 32 ++++++++++++++------------------ 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/novelwriter/core/project.py b/novelwriter/core/project.py index 4a399c24..3ce2160a 100644 --- a/novelwriter/core/project.py +++ b/novelwriter/core/project.py @@ -36,7 +36,7 @@ from collections.abc import Iterable from PyQt5.QtCore import QCoreApplication from novelwriter import CONFIG, SHARED, __version__, __hexversion__ -from novelwriter.enum import nwItemType, nwItemClass, nwItemLayout +from novelwriter.enum import nwItemType, nwItemClass, nwItemLayout, nwStatusShape from novelwriter.error import logException from novelwriter.constants import trConst, nwLabels from novelwriter.core.tree import NWTree @@ -461,14 +461,15 @@ class NWProject: def setDefaultStatusImport(self) -> None: """Set the default status and importance values.""" - self._data.itemStatus.write(None, self.tr("New"), (100, 100, 100)) - self._data.itemStatus.write(None, self.tr("Note"), (200, 50, 0)) - self._data.itemStatus.write(None, self.tr("Draft"), (200, 150, 0)) - self._data.itemStatus.write(None, self.tr("Finished"), (50, 200, 0)) - self._data.itemImport.write(None, self.tr("New"), (100, 100, 100)) - self._data.itemImport.write(None, self.tr("Minor"), (200, 50, 0)) - self._data.itemImport.write(None, self.tr("Major"), (200, 150, 0)) - self._data.itemImport.write(None, self.tr("Main"), (50, 200, 0)) + square = nwStatusShape.SQUARE + self._data.itemStatus.write(None, self.tr("New"), (100, 100, 100), square) + self._data.itemStatus.write(None, self.tr("Note"), (200, 50, 0), square) + self._data.itemStatus.write(None, self.tr("Draft"), (200, 150, 0), square) + self._data.itemStatus.write(None, self.tr("Finished"), (50, 200, 0), square) + self._data.itemImport.write(None, self.tr("New"), (100, 100, 100), square) + self._data.itemImport.write(None, self.tr("Minor"), (200, 50, 0), square) + self._data.itemImport.write(None, self.tr("Major"), (200, 150, 0), square) + self._data.itemImport.write(None, self.tr("Main"), (50, 200, 0), square) return def setProjectLang(self, language: str | None) -> None: @@ -596,8 +597,9 @@ class NWProject: key = entry.get("key", None) name = entry.get("name", "") cols = entry.get("cols", (100, 100, 100)) + shape = entry.get("shape", nwStatusShape.SQUARE) if name: - order.append(target.write(key, name, cols)) + order.append(target.write(key, name, cols, shape)) for key in delete: target.remove(key) diff --git a/novelwriter/core/projectxml.py b/novelwriter/core/projectxml.py index 52db58f6..bb2ade31 100644 --- a/novelwriter/core/projectxml.py +++ b/novelwriter/core/projectxml.py @@ -46,7 +46,7 @@ if TYPE_CHECKING: # pragma: no cover logger = logging.getLogger(__name__) FILE_VERSION = "1.5" # The current project file format version -FILE_REVISION = "3" # The current project file format revision +FILE_REVISION = "4" # The current project file format revision HEX_VERSION = 0x0105 NUM_VERSION = { @@ -109,6 +109,8 @@ class ProjectXMLReader: Rev 2: Drops the title node from project and adds the TEMPLATE class for items. 2.3 Beta 1. Rev 3: Added TEMPLATE class. 2.3. + Rev 4: Added shape attribute to status and importance entry + nodes. 2.5. """ def __init__(self, path: str | Path) -> None: @@ -436,7 +438,8 @@ class ProjectXMLReader: green = checkInt(xEntry.attrib.get("green", 0), 0) blue = checkInt(xEntry.attrib.get("blue", 0), 0) count = checkInt(xEntry.attrib.get("count", 0), 0) - sObject.write(key, xEntry.text or "", (red, green, blue), count) + shape = xEntry.attrib.get("shape", "") + sObject.write(key, xEntry.text or "", (red, green, blue), shape, count) return def _parseDictKeyText(self, xItem: ET.Element) -> dict: diff --git a/novelwriter/core/status.py b/novelwriter/core/status.py index ec45a6c3..0470bac0 100644 --- a/novelwriter/core/status.py +++ b/novelwriter/core/status.py @@ -57,7 +57,7 @@ class NWStatus: self._default = None self._iPX = CONFIG.pxInt(24) - self._defaultIcon = self._createIcon(100, 100, 100) + self._defaultIcon = self._createIcon(100, 100, 100, nwStatusShape.SQUARE) if self._type == self.STATUS: self._prefix = "s" @@ -68,7 +68,8 @@ class NWStatus: return - def write(self, key: str | None, name: str, col: tuple, count: int | None = None) -> str: + def write(self, key: str | None, name: str, col: tuple, shape: nwStatusShape | str, + count: int | None = None) -> str: """Add or update a status entry. If the key is invalid, a new key is generated. """ @@ -83,14 +84,21 @@ class NWStatus: cG = minmax(col[1], 0, 255) cB = minmax(col[2], 0, 255) name = simplified(name) + if not isinstance(shape, nwStatusShape): + if shape in nwStatusShape.__members__: + shape = nwStatusShape[shape] + else: + shape = nwStatusShape.SQUARE + if count is None: count = self._store.get(key, {}).get("count", 0) self._store[key] = { "name": name, - "icon": self._createIcon(cR, cG, cB), + "icon": self._createIcon(cR, cG, cB, shape), "cols": (cR, cG, cB), "count": count, + "shape": shape, } if self._default is None: @@ -198,20 +206,10 @@ class NWStatus: "red": str(data["cols"][0]), "green": str(data["cols"][1]), "blue": str(data["cols"][2]), + "shape": data["shape"].name, }) return - def unpack(self, data: dict) -> None: - """Unpack a data dictionary and set the class values.""" - self._store = {} - self._default = None - for key, entry in data.items(): - label = entry.get("label", "") - colour = entry.get("colour", (100, 100, 100)) - count = entry.get("count", 0) - self.write(key, label, colour, count) - return - ## # Internal Functions ## @@ -241,16 +239,14 @@ class NWStatus: return False return True - def _createIcon(self, red: int, green: int, blue: int) -> QIcon: + def _createIcon(self, red: int, green: int, blue: int, shape: nwStatusShape) -> QIcon: """Generate an icon for a status label.""" pixmap = QPixmap(48, 48) pixmap.fill(QtTransparent) - path = _SHAPES.getShape(nwStatusShape.DIAMOND) - painter = QPainter(pixmap) painter.setRenderHint(QtPaintAnitAlias) - painter.fillPath(path, QColor(red, green, blue)) + painter.fillPath(_SHAPES.getShape(shape), QColor(red, green, blue)) painter.end() return QIcon(pixmap.scaled(