Simplify further how status labels are added and updated

This commit is contained in:
Veronica Berglyd Olsen
2024-04-10 21:38:43 +02:00
parent 63d2f5c57d
commit f17302439e
5 changed files with 69 additions and 142 deletions
+1 -1
View File
@@ -104,7 +104,7 @@ class DocMerger:
docText = self._project.storage.getDocumentText(srcHandle).rstrip("\n")
if addComment:
docInfo = srcItem.describeMe()
docSt, _ = srcItem.getImportStatus(incIcon=False)
docSt, _ = srcItem.getImportStatus()
cmtLine = f"% {cmtPrefix} {docInfo}: {srcItem.itemName} [{docSt}]\n\n"
docText = cmtLine + docText
+21 -43
View File
@@ -26,34 +26,32 @@ from __future__ import annotations
import json
import logging
from collections.abc import Iterable
from enum import Enum
from functools import partial
from pathlib import Path
from time import time
from typing import TYPE_CHECKING
from pathlib import Path
from functools import partial
from collections.abc import Iterable
from PyQt5.QtCore import QCoreApplication
from novelwriter import CONFIG, SHARED, __version__, __hexversion__
from novelwriter.core.status import StatusEntry
from novelwriter.enum import nwItemType, nwItemClass, nwItemLayout
from novelwriter.error import logException
from novelwriter.constants import trConst, nwLabels
from novelwriter.core.tree import NWTree
from novelwriter.core.index import NWIndex
from novelwriter.core.options import OptionState
from novelwriter.core.storage import NWStorage, NWStorageOpen
from novelwriter.core.sessions import NWSessionLog
from novelwriter.core.projectxml import ProjectXMLReader, ProjectXMLWriter, XMLReadState
from novelwriter.core.projectdata import NWProjectData
from novelwriter.common import (
checkStringNone, formatInt, formatTimeStamp, getFileSize, hexToInt, makeFileNameSafe, minmax
)
from novelwriter.constants import trConst, nwLabels
from novelwriter.core.index import NWIndex
from novelwriter.core.options import OptionState
from novelwriter.core.projectdata import NWProjectData
from novelwriter.core.projectxml import ProjectXMLReader, ProjectXMLWriter, XMLReadState
from novelwriter.core.sessions import NWSessionLog
from novelwriter.core.storage import NWStorage, NWStorageOpen
from novelwriter.core.tree import NWTree
from novelwriter.enum import nwItemType, nwItemClass, nwItemLayout
from novelwriter.error import logException
if TYPE_CHECKING: # pragma: no cover
from novelwriter.core.item import NWItem
from novelwriter.core.status import NWStatus
logger = logging.getLogger(__name__)
@@ -462,14 +460,14 @@ class NWProject:
def setDefaultStatusImport(self) -> None:
"""Set the default status and importance values."""
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")
self._data.itemStatus.add(None, self.tr("New"), (100, 100, 100), "SQUARE", 0)
self._data.itemStatus.add(None, self.tr("Note"), (200, 50, 0), "SQUARE", 0)
self._data.itemStatus.add(None, self.tr("Draft"), (200, 150, 0), "SQUARE", 0)
self._data.itemStatus.add(None, self.tr("Finished"), (50, 200, 0), "SQUARE", 0)
self._data.itemImport.add(None, self.tr("New"), (100, 100, 100), "SQUARE", 0)
self._data.itemImport.add(None, self.tr("Minor"), (200, 50, 0), "SQUARE", 0)
self._data.itemImport.add(None, self.tr("Major"), (200, 150, 0), "SQUARE", 0)
self._data.itemImport.add(None, self.tr("Main"), (50, 200, 0), "SQUARE", 0)
return
def setProjectLang(self, language: str | None) -> None:
@@ -492,14 +490,6 @@ class NWProject:
self.setProjectChanged(True)
return
def setStatus(self, update: list[tuple[str | None, StatusEntry]], remove: list[str]) -> None:
"""Update the list of novel file status flags."""
return self._setStatusImport(update, remove, self._data.itemStatus)
def setImport(self, update: list[tuple[str | None, StatusEntry]], remove: list[str]) -> None:
"""Update the list of note file importance flags."""
return self._setStatusImport(update, remove, self._data.itemImport)
def setProjectChanged(self, status: bool) -> bool:
"""Toggle the project changed flag, and propagate the
information to the GUI statusbar.
@@ -585,18 +575,6 @@ class NWProject:
# Internal Functions
##
def _setStatusImport(self, update: list[tuple[str | None, StatusEntry]],
remove: list[str], target: NWStatus) -> None:
"""Update the list of novel file status or importance flags, and
delete those that have been requested deleted.
"""
if update or remove:
order = [target.write(k, e.name, e.color, e.shape) for k, e in update]
for key in remove:
target.remove(key)
target.reorder(order)
return
def _loadProjectLocalisation(self) -> bool:
"""Load the language data for the current project language."""
if self._data.language is None or CONFIG._nwLangPath is None:
+1 -1
View File
@@ -439,7 +439,7 @@ class ProjectXMLReader:
blue = checkInt(xEntry.attrib.get("blue", 0), 0)
count = checkInt(xEntry.attrib.get("count", 0), 0)
shape = xEntry.attrib.get("shape", "")
sObject.write(key, xEntry.text or "", (red, green, blue), shape, count)
sObject.add(key, xEntry.text or "", (red, green, blue), shape, count)
return
def _parseDictKeyText(self, xItem: ET.Element) -> dict:
+25 -62
View File
@@ -35,7 +35,7 @@ from typing import TYPE_CHECKING, Literal
from PyQt5.QtCore import QPointF, Qt
from PyQt5.QtGui import QIcon, QPainter, QPainterPath, QPixmap, QColor, QPolygonF
from novelwriter import CONFIG
from novelwriter import SHARED
from novelwriter.common import simplified
from novelwriter.enum import nwStatusShape
from novelwriter.types import QtPaintAnitAlias, QtTransparent
@@ -77,7 +77,7 @@ class NWStatus:
self._store: dict[str, StatusEntry] = {}
self._default = None
self._iPX = CONFIG.pxInt(24)
self._iPx = SHARED.theme.baseIconHeight
if self._type == self.STATUS:
self._prefix = "s"
@@ -103,62 +103,42 @@ class NWStatus:
# Methods
##
def write(self, key: str | None, name: str, color: tuple[int, int, int] | QColor,
shape: nwStatusShape | str, count: int = 0) -> str:
def add(self, key: str | None, name: str, color: tuple[int, int, int],
shape: str, count: int) -> str:
"""Add or update a status entry. If the key is invalid, a new
key is generated.
"""
if not self._isKey(key):
key = self._newKey()
if isinstance(color, QColor):
qColor = color
elif isinstance(color, tuple) and len(color) == 3:
if isinstance(color, tuple) and len(color) == 3:
qColor = QColor(*color)
else:
qColor = QColor(100, 100, 100)
if not isinstance(shape, nwStatusShape):
try:
shape = nwStatusShape[shape]
except KeyError:
shape = nwStatusShape.SQUARE
try:
iShape = nwStatusShape[shape]
except KeyError:
iShape = nwStatusShape.SQUARE
key = self._checkKey(key)
name = simplified(name)
icon = self.createIcon(self._iPX, qColor, shape)
if key and key in self._store:
entry = self._store[key]
entry.name = name
entry.color = qColor
entry.shape = shape
entry.icon = icon
entry.count = count
else:
self._store[key] = StatusEntry(name, qColor, shape, icon, count)
icon = self.createIcon(self._iPx, qColor, iShape)
self._store[key] = StatusEntry(name, qColor, iShape, icon, count)
if self._default is None:
self._default = key
return key
def remove(self, key: str) -> bool:
"""Remove an entry in the list, except if the count > 0."""
if key not in self._store:
return False
if self._store[key].count > 0:
return False
def update(self, update: list[tuple[str | None, StatusEntry]]) -> None:
"""Update the list of statuses, and from removed list."""
self._store.clear()
for key, entry in update:
self._store[self._checkKey(key)] = entry
del self._store[key]
# Check if we need a new default
if self._default not in self._store:
self._default = next(iter(self._store)) if self._store else None
keys = list(self._store.keys())
if key == self._default:
if len(keys) > 0:
self._default = keys[0]
else:
self._default = None
return True
return
def check(self, value: str) -> str:
"""Check the key against the stored status names."""
@@ -168,27 +148,6 @@ class NWStatus:
return self._default
return ""
def reorder(self, order: list[str]) -> bool:
"""Reorder the items according to list."""
if len(order) != len(self._store):
logger.error("Length mismatch between new and old order")
return False
if order == list(self._store.keys()):
return False
store = {}
for key in order:
if key in self._store:
store[key] = self._store[key]
else:
logger.error("Unknown key '%s' in order", key)
return False
self._store = store
return True
def resetCounts(self) -> None:
"""Clear the counts of references to the status entries."""
for key in self._store:
@@ -264,6 +223,10 @@ class NWStatus:
return False
return True
def _checkKey(self, key: str | None) -> str:
"""Check key is valid, and if not, generate one."""
return key if self._isKey(key) else self._newKey()
# END Class NWStatus
+21 -35
View File
@@ -181,19 +181,16 @@ class GuiProjectSettings(QDialog):
rebuildTrees = False
if self.statusPage.wasChanged:
update, remove = self.statusPage.getNewList()
project.setStatus(update, remove)
if self.statusPage.changed:
project.data.itemStatus.update(self.statusPage.getNewList())
rebuildTrees = True
if self.importPage.wasChanged:
update, remove = self.importPage.getNewList()
project.setImport(update, remove)
if self.importPage.changed:
project.data.itemImport.update(self.importPage.getNewList())
rebuildTrees = True
if self.replacePage.wasChanged:
update = self.replacePage.getNewList()
project.data.setAutoReplace(update)
if self.replacePage.changed:
project.data.setAutoReplace(self.replacePage.getNewList())
self.newProjectSettingsReady.emit(rebuildTrees)
QApplication.processEvents()
@@ -327,7 +324,6 @@ class _StatusPage(NFixedPage):
)
self._changed = False
self._colDeleted: list[str] = []
self._selColour = QColor(100, 100, 100)
self._iPx = SHARED.theme.baseIconHeight
@@ -415,7 +411,7 @@ class _StatusPage(NFixedPage):
return
@property
def wasChanged(self) -> bool:
def changed(self) -> bool:
"""The user changed these settings."""
return self._changed
@@ -423,7 +419,7 @@ class _StatusPage(NFixedPage):
# Methods
##
def getNewList(self) -> tuple[list[tuple[str | None, StatusEntry]], list[str]]:
def getNewList(self) -> list[tuple[str | None, StatusEntry]]:
"""Return list of entries."""
if self._changed:
update = []
@@ -432,8 +428,8 @@ class _StatusPage(NFixedPage):
key = item.data(self.C_DATA, self.D_KEY)
entry = item.data(self.C_DATA, self.D_ENTRY)
update.append((key, entry))
return update, self._colDeleted
return [], []
return update
return []
def columnWidth(self) -> int:
"""Return the size of the header column."""
@@ -478,7 +474,6 @@ class _StatusPage(NFixedPage):
SHARED.error(self.tr("Cannot delete a status item that is in use."))
else:
self.listBox.takeTopLevelItem(iRow)
self._colDeleted.append(item.data(self.C_DATA, self.D_KEY))
self._changed = True
return
@@ -543,24 +538,15 @@ class _StatusPage(NFixedPage):
def _moveItem(self, step: int) -> None:
"""Move and item up or down step."""
selItem = self._getSelectedItem()
if selItem is None:
return
tIndex = self.listBox.indexOfTopLevelItem(selItem)
nChild = self.listBox.topLevelItemCount()
nIndex = tIndex + step
if nIndex < 0 or nIndex >= nChild:
return
cItem = self.listBox.takeTopLevelItem(tIndex)
self.listBox.insertTopLevelItem(nIndex, cItem)
self.listBox.clearSelection()
if cItem is not None:
cItem.setSelected(True)
self._changed = True
if item := self._getSelectedItem():
tIdx = self.listBox.indexOfTopLevelItem(item)
nItm = self.listBox.topLevelItemCount()
nIdx = tIdx + step
if (0 <= nIdx < nItm) and (cItem := self.listBox.takeTopLevelItem(tIdx)):
self.listBox.insertTopLevelItem(nIdx, cItem)
self.listBox.clearSelection()
cItem.setSelected(True)
self._changed = True
return
def _getSelectedItem(self) -> QTreeWidgetItem | None:
@@ -665,7 +651,7 @@ class _ReplacePage(NFixedPage):
return
@property
def wasChanged(self) -> bool:
def changed(self) -> bool:
"""The user changed these settings."""
return self._changed
@@ -673,7 +659,7 @@ class _ReplacePage(NFixedPage):
# Methods
##
def getNewList(self) -> dict:
def getNewList(self) -> dict[str, str]:
"""Extract the list from the widget."""
new = {}
for n in range(self.listBox.topLevelItemCount()):