Clean up a few things in project classes

This commit is contained in:
Veronica Berglyd Olsen
2023-08-24 19:45:08 +02:00
parent f339ec2471
commit 4507489f0b
8 changed files with 65 additions and 74 deletions
+9 -13
View File
@@ -31,7 +31,7 @@ from typing import TYPE_CHECKING, Iterator
from pathlib import Path
from functools import partial
from PyQt5.QtCore import QCoreApplication, QObject, pyqtSignal
from PyQt5.QtCore import QCoreApplication
from novelwriter import CONFIG, SHARED, __version__, __hexversion__
from novelwriter.enum import nwItemType, nwItemClass, nwItemLayout
@@ -55,13 +55,9 @@ if TYPE_CHECKING: # pragma: no cover
logger = logging.getLogger(__name__)
class NWProject(QObject):
class NWProject:
statusChanged = pyqtSignal(bool)
statusMessage = pyqtSignal(str)
def __init__(self, parent: QObject | None = None) -> None:
super().__init__(parent=parent)
def __init__(self) -> None:
# Core Elements
self._options = OptionState(self) # Project-specific GUI options
@@ -206,7 +202,7 @@ class NWProject(QObject):
def trashFolder(self) -> str:
"""Add the special trash root folder to the project."""
trashHandle = self._tree.trashRoot()
trashHandle = self._tree.trashRoot
if trashHandle is None:
label = trConst(nwLabels.CLASS_NAME[nwItemClass.TRASH])
return self._tree.create(label, None, nwItemType.ROOT, nwItemClass.TRASH)
@@ -331,7 +327,7 @@ class NWProject(QObject):
self.setProjectChanged(False)
self._valid = True
self.statusMessage.emit(self.tr("Opened Project: {0}").format(self._data.name))
SHARED.newStatusMessage(self.tr("Opened Project: {0}").format(self._data.name))
return True
@@ -381,7 +377,7 @@ class NWProject(QObject):
)
self._storage.writeLockFile()
self.statusMessage.emit(self.tr("Saved Project: {0}").format(self._data.name))
SHARED.newStatusMessage(self.tr("Saved Project: {0}").format(self._data.name))
self.setProjectChanged(False)
return True
@@ -403,7 +399,7 @@ class NWProject(QObject):
return False
logger.info("Backing up project")
self.statusMessage.emit(self.tr("Backing up project ..."))
SHARED.newStatusMessage(self.tr("Backing up project ..."))
if not self._data.name:
SHARED.error(self.tr(
@@ -434,7 +430,7 @@ class NWProject(QObject):
SHARED.error(self.tr("Could not write backup archive."))
return False
self.statusMessage.emit(self.tr("Project backed up to '{0}'").format(str(archName)))
SHARED.newStatusMessage(self.tr("Project backed up to '{0}'").format(str(archName)))
return True
@@ -488,7 +484,7 @@ class NWProject(QObject):
"""
if isinstance(status, bool):
self._changed = status
self.statusChanged.emit(self._changed)
SHARED.setGlobalProjectState(self._changed)
return self._changed
##
+14 -11
View File
@@ -40,6 +40,8 @@ if TYPE_CHECKING: # pragma: no cover
logger = logging.getLogger(__name__)
MAX_DEPTH = 1000 # Cap of tree traversing for loops (recursion limit)
class NWTree:
"""Core: Project Tree Data Class
@@ -59,7 +61,7 @@ class NWTree:
also used for file names.
"""
MAX_DEPTH = 1000 # Cap of tree traversing for loops
__slots__ = ("_project", "_tree", "_order", "_roots", "_trash", "_changed")
def __init__(self, project: NWProject) -> None:
@@ -74,6 +76,15 @@ class NWTree:
return
##
# Properties
##
@property
def trashRoot(self) -> str | None:
"""Return the handle of the trash folder, or None."""
return self._trash
##
# Class Methods
##
@@ -320,7 +331,7 @@ class NWTree:
return False
iItem = tItem
for _ in range(self.MAX_DEPTH):
for _ in range(MAX_DEPTH):
if iItem.itemParent is None:
tItem.setRoot(iItem.itemHandle)
tItem.setClassDefaults(iItem.itemClass)
@@ -349,7 +360,7 @@ class NWTree:
tItem = self.__getitem__(tHandle)
if tItem is not None:
tTree.append(tHandle)
for _ in range(self.MAX_DEPTH):
for _ in range(MAX_DEPTH):
if tItem.itemParent is None:
return tTree
else:
@@ -400,14 +411,6 @@ class NWTree:
return True
return False
def trashRoot(self) -> str | None:
"""Returns the handle of the trash folder, or None if there
isn't one.
"""
if self._trash:
return self._trash
return None
def findRoot(self, itemClass: nwItemClass | None) -> str | None:
"""Find the first root item for a given class."""
for aRoot in self._roots:
+3 -3
View File
@@ -798,7 +798,7 @@ class GuiProjectTree(QTreeWidget):
logger.error("There is no item to delete")
return False
trashHandle = SHARED.project.tree.trashRoot()
trashHandle = SHARED.project.tree.trashRoot
if tHandle == trashHandle:
logger.error("Cannot delete the Trash folder")
return False
@@ -823,7 +823,7 @@ class GuiProjectTree(QTreeWidget):
logger.error("No project open")
return False
trashHandle = SHARED.project.tree.trashRoot()
trashHandle = SHARED.project.tree.trashRoot
logger.debug("Emptying Trash folder")
if trashHandle is None:
@@ -1201,7 +1201,7 @@ class GuiProjectTree(QTreeWidget):
# Trash Folder
# ============
trashHandle = SHARED.project.tree.trashRoot()
trashHandle = SHARED.project.tree.trashRoot
if tItem.itemHandle == trashHandle and trashHandle is not None:
# The trash folder only has one option
aEmptyTrash = ctxMenu.addAction(self.tr("Empty Trash"))
+2 -2
View File
@@ -590,8 +590,8 @@ class GuiMain(QMainWindow):
return True
def openNextDocument(self, tHandle: str, wrapAround: bool = False) -> bool:
"""Opens the next document in the project tree, following the
document with the given handle. Stops when reaching the end.
"""Open the next document in the project tree, following the
document with the given handle. Stop when reaching the end.
"""
if not SHARED.hasProject:
logger.error("No project open")
+21 -27
View File
@@ -29,7 +29,7 @@ from time import time
from typing import TYPE_CHECKING
from pathlib import Path
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot
from PyQt5.QtCore import QObject, pyqtSignal
from PyQt5.QtWidgets import QMessageBox, QWidget
if TYPE_CHECKING: # pragma: no cover
@@ -84,7 +84,7 @@ class SharedData(QObject):
@property
def hasProject(self) -> bool:
"""Return True of the project instance is populated."""
"""Return True if the project instance is populated."""
return self.project.isValid
@property
@@ -107,9 +107,9 @@ class SharedData(QObject):
##
def initSharedData(self, gui: GuiMain, theme: GuiTheme) -> None:
"""Initialise the UserData instance. This must be called as soon
as the Main GUI is created to ensure the SHARED singleton has the
properties needed for operation.
"""Initialise the SharedData instance. This must be called as
soon as the Main GUI is created to ensure the SHARED singleton
has the properties needed for operation.
"""
self._gui = gui
self._theme = theme
@@ -159,6 +159,20 @@ class SharedData(QObject):
self._idleRefTime = currTime
return
def newStatusMessage(self, message: str) -> None:
"""Request a new status message. This is a callable function for
core classes that cannot emit signals on their own.
"""
self.projectStatusMessage.emit(message)
return
def setGlobalProjectState(self, state: bool) -> None:
"""Change the global project status. This is a callable function
for core classes that cannot emit signals on their own.
"""
self.projectStatusChanged.emit(state)
return
##
# Alert Boxes
##
@@ -201,22 +215,6 @@ class SharedData(QObject):
self._alert.exec_()
return self._alert.result() == QMessageBox.Yes
##
# Internal Slots
##
@pyqtSlot(bool)
def _emitProjectStatusChange(self, state: bool) -> None:
"""Forward the project status slot."""
self.projectStatusChanged.emit(state)
return
@pyqtSlot(str)
def _emitProjectStatusMeesage(self, message: str) -> None:
"""Forward the project message slot."""
self.projectStatusMessage.emit(message)
return
##
# Internal Functions
##
@@ -225,12 +223,8 @@ class SharedData(QObject):
"""Create a new project instance."""
from novelwriter.core.project import NWProject
if isinstance(self._project, NWProject):
self._project.statusChanged.disconnect()
self._project.statusMessage.disconnect()
self._project.deleteLater()
self._project = NWProject(self)
self._project.statusChanged.connect(self._emitProjectStatusChange)
self._project.statusMessage.connect(self._emitProjectStatusMeesage)
del self._project
self._project = NWProject()
return
def _resetIdleTimer(self) -> None: