Add status icon shape to project XML
This commit is contained in:
+12
-10
@@ -36,7 +36,7 @@ from collections.abc import Iterable
|
|||||||
from PyQt5.QtCore import QCoreApplication
|
from PyQt5.QtCore import QCoreApplication
|
||||||
|
|
||||||
from novelwriter import CONFIG, SHARED, __version__, __hexversion__
|
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.error import logException
|
||||||
from novelwriter.constants import trConst, nwLabels
|
from novelwriter.constants import trConst, nwLabels
|
||||||
from novelwriter.core.tree import NWTree
|
from novelwriter.core.tree import NWTree
|
||||||
@@ -461,14 +461,15 @@ class NWProject:
|
|||||||
|
|
||||||
def setDefaultStatusImport(self) -> None:
|
def setDefaultStatusImport(self) -> None:
|
||||||
"""Set the default status and importance values."""
|
"""Set the default status and importance values."""
|
||||||
self._data.itemStatus.write(None, self.tr("New"), (100, 100, 100))
|
square = nwStatusShape.SQUARE
|
||||||
self._data.itemStatus.write(None, self.tr("Note"), (200, 50, 0))
|
self._data.itemStatus.write(None, self.tr("New"), (100, 100, 100), square)
|
||||||
self._data.itemStatus.write(None, self.tr("Draft"), (200, 150, 0))
|
self._data.itemStatus.write(None, self.tr("Note"), (200, 50, 0), square)
|
||||||
self._data.itemStatus.write(None, self.tr("Finished"), (50, 200, 0))
|
self._data.itemStatus.write(None, self.tr("Draft"), (200, 150, 0), square)
|
||||||
self._data.itemImport.write(None, self.tr("New"), (100, 100, 100))
|
self._data.itemStatus.write(None, self.tr("Finished"), (50, 200, 0), square)
|
||||||
self._data.itemImport.write(None, self.tr("Minor"), (200, 50, 0))
|
self._data.itemImport.write(None, self.tr("New"), (100, 100, 100), square)
|
||||||
self._data.itemImport.write(None, self.tr("Major"), (200, 150, 0))
|
self._data.itemImport.write(None, self.tr("Minor"), (200, 50, 0), square)
|
||||||
self._data.itemImport.write(None, self.tr("Main"), (50, 200, 0))
|
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
|
return
|
||||||
|
|
||||||
def setProjectLang(self, language: str | None) -> None:
|
def setProjectLang(self, language: str | None) -> None:
|
||||||
@@ -596,8 +597,9 @@ class NWProject:
|
|||||||
key = entry.get("key", None)
|
key = entry.get("key", None)
|
||||||
name = entry.get("name", "")
|
name = entry.get("name", "")
|
||||||
cols = entry.get("cols", (100, 100, 100))
|
cols = entry.get("cols", (100, 100, 100))
|
||||||
|
shape = entry.get("shape", nwStatusShape.SQUARE)
|
||||||
if name:
|
if name:
|
||||||
order.append(target.write(key, name, cols))
|
order.append(target.write(key, name, cols, shape))
|
||||||
|
|
||||||
for key in delete:
|
for key in delete:
|
||||||
target.remove(key)
|
target.remove(key)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ if TYPE_CHECKING: # pragma: no cover
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
FILE_VERSION = "1.5" # The current project file format version
|
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
|
HEX_VERSION = 0x0105
|
||||||
|
|
||||||
NUM_VERSION = {
|
NUM_VERSION = {
|
||||||
@@ -109,6 +109,8 @@ class ProjectXMLReader:
|
|||||||
Rev 2: Drops the title node from project and adds the TEMPLATE
|
Rev 2: Drops the title node from project and adds the TEMPLATE
|
||||||
class for items. 2.3 Beta 1.
|
class for items. 2.3 Beta 1.
|
||||||
Rev 3: Added TEMPLATE class. 2.3.
|
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:
|
def __init__(self, path: str | Path) -> None:
|
||||||
@@ -436,7 +438,8 @@ class ProjectXMLReader:
|
|||||||
green = checkInt(xEntry.attrib.get("green", 0), 0)
|
green = checkInt(xEntry.attrib.get("green", 0), 0)
|
||||||
blue = checkInt(xEntry.attrib.get("blue", 0), 0)
|
blue = checkInt(xEntry.attrib.get("blue", 0), 0)
|
||||||
count = checkInt(xEntry.attrib.get("count", 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
|
return
|
||||||
|
|
||||||
def _parseDictKeyText(self, xItem: ET.Element) -> dict:
|
def _parseDictKeyText(self, xItem: ET.Element) -> dict:
|
||||||
|
|||||||
+14
-18
@@ -57,7 +57,7 @@ class NWStatus:
|
|||||||
self._default = None
|
self._default = None
|
||||||
|
|
||||||
self._iPX = CONFIG.pxInt(24)
|
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:
|
if self._type == self.STATUS:
|
||||||
self._prefix = "s"
|
self._prefix = "s"
|
||||||
@@ -68,7 +68,8 @@ class NWStatus:
|
|||||||
|
|
||||||
return
|
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
|
"""Add or update a status entry. If the key is invalid, a new
|
||||||
key is generated.
|
key is generated.
|
||||||
"""
|
"""
|
||||||
@@ -83,14 +84,21 @@ class NWStatus:
|
|||||||
cG = minmax(col[1], 0, 255)
|
cG = minmax(col[1], 0, 255)
|
||||||
cB = minmax(col[2], 0, 255)
|
cB = minmax(col[2], 0, 255)
|
||||||
name = simplified(name)
|
name = simplified(name)
|
||||||
|
if not isinstance(shape, nwStatusShape):
|
||||||
|
if shape in nwStatusShape.__members__:
|
||||||
|
shape = nwStatusShape[shape]
|
||||||
|
else:
|
||||||
|
shape = nwStatusShape.SQUARE
|
||||||
|
|
||||||
if count is None:
|
if count is None:
|
||||||
count = self._store.get(key, {}).get("count", 0)
|
count = self._store.get(key, {}).get("count", 0)
|
||||||
|
|
||||||
self._store[key] = {
|
self._store[key] = {
|
||||||
"name": name,
|
"name": name,
|
||||||
"icon": self._createIcon(cR, cG, cB),
|
"icon": self._createIcon(cR, cG, cB, shape),
|
||||||
"cols": (cR, cG, cB),
|
"cols": (cR, cG, cB),
|
||||||
"count": count,
|
"count": count,
|
||||||
|
"shape": shape,
|
||||||
}
|
}
|
||||||
|
|
||||||
if self._default is None:
|
if self._default is None:
|
||||||
@@ -198,20 +206,10 @@ class NWStatus:
|
|||||||
"red": str(data["cols"][0]),
|
"red": str(data["cols"][0]),
|
||||||
"green": str(data["cols"][1]),
|
"green": str(data["cols"][1]),
|
||||||
"blue": str(data["cols"][2]),
|
"blue": str(data["cols"][2]),
|
||||||
|
"shape": data["shape"].name,
|
||||||
})
|
})
|
||||||
return
|
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
|
# Internal Functions
|
||||||
##
|
##
|
||||||
@@ -241,16 +239,14 @@ class NWStatus:
|
|||||||
return False
|
return False
|
||||||
return True
|
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."""
|
"""Generate an icon for a status label."""
|
||||||
pixmap = QPixmap(48, 48)
|
pixmap = QPixmap(48, 48)
|
||||||
pixmap.fill(QtTransparent)
|
pixmap.fill(QtTransparent)
|
||||||
|
|
||||||
path = _SHAPES.getShape(nwStatusShape.DIAMOND)
|
|
||||||
|
|
||||||
painter = QPainter(pixmap)
|
painter = QPainter(pixmap)
|
||||||
painter.setRenderHint(QtPaintAnitAlias)
|
painter.setRenderHint(QtPaintAnitAlias)
|
||||||
painter.fillPath(path, QColor(red, green, blue))
|
painter.fillPath(_SHAPES.getShape(shape), QColor(red, green, blue))
|
||||||
painter.end()
|
painter.end()
|
||||||
|
|
||||||
return QIcon(pixmap.scaled(
|
return QIcon(pixmap.scaled(
|
||||||
|
|||||||
Reference in New Issue
Block a user