Move project data class to project file
This commit is contained in:
+314
-16
@@ -4,7 +4,8 @@ novelWriter – Project Wrapper
|
||||
Data class for novelWriter projects
|
||||
|
||||
File History:
|
||||
Created: 2018-09-29 [0.0.1]
|
||||
Created: 2018-09-29 [0.0.1] NWProject
|
||||
Created: 2022-10-30 [2.0rc1] NWProjectData
|
||||
|
||||
This file is a part of novelWriter
|
||||
Copyright 2018–2022, Veronica Berglyd Olsen
|
||||
@@ -32,38 +33,40 @@ import novelwriter
|
||||
from time import time
|
||||
from functools import partial
|
||||
|
||||
from PyQt5.QtCore import QCoreApplication
|
||||
from PyQt5.QtCore import QCoreApplication, QObject, pyqtSignal
|
||||
|
||||
from novelwriter.enum import nwItemType, nwItemClass, nwItemLayout, nwAlert
|
||||
from novelwriter.error import logException
|
||||
from novelwriter.common import (
|
||||
checkStringNone, isHandle, formatTimeStamp, makeFileNameSafe, hexToInt,
|
||||
minmax, simplified
|
||||
)
|
||||
from novelwriter.constants import trConst, nwFiles, nwLabels
|
||||
from novelwriter.core.tree import NWTree
|
||||
from novelwriter.core.item import NWItem
|
||||
from novelwriter.core.index import NWIndex
|
||||
from novelwriter.core.status import NWStatus
|
||||
from novelwriter.core.options import OptionState
|
||||
from novelwriter.core.document import NWDoc
|
||||
from novelwriter.core.projectxml import ProjectXMLReader, ProjectXMLWriter, XMLReadState
|
||||
from novelwriter.core.projectdata import NWProjectData
|
||||
from novelwriter.common import (
|
||||
checkBool, checkInt, checkString, checkStringNone, formatTimeStamp, hexToInt, isHandle,
|
||||
makeFileNameSafe, minmax, simplified,
|
||||
)
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class NWProject:
|
||||
class NWProject(QObject):
|
||||
|
||||
FILE_VERSION = "1.4" # The current project file format version
|
||||
projectStatusChanged = pyqtSignal(bool)
|
||||
|
||||
def __init__(self, mainGui):
|
||||
super().__init__(parent=mainGui)
|
||||
|
||||
# Internal
|
||||
self.mainConf = novelwriter.CONFIG
|
||||
self.mainGui = mainGui
|
||||
|
||||
# Project Data
|
||||
self._data = NWProjectData()
|
||||
self._data = NWProjectData(self)
|
||||
|
||||
# Core Elements
|
||||
self._optState = OptionState(self) # Project-specific GUI options
|
||||
@@ -240,7 +243,7 @@ class NWProject:
|
||||
# Project Tree
|
||||
self._projTree.clear()
|
||||
|
||||
self._data = NWProjectData()
|
||||
self._data = NWProjectData(self)
|
||||
|
||||
# Project Settings
|
||||
self.projPath = None
|
||||
@@ -446,7 +449,7 @@ class NWProject:
|
||||
# Open The Project XML File
|
||||
# =========================
|
||||
|
||||
self._data = NWProjectData()
|
||||
self._data = NWProjectData(self)
|
||||
xmlReader = ProjectXMLReader(fileName)
|
||||
xmlParsed = xmlReader.read(self._data)
|
||||
|
||||
@@ -857,13 +860,10 @@ class NWProject:
|
||||
information to the GUI statusbar.
|
||||
"""
|
||||
self._projChanged = bValue
|
||||
self.mainGui.mainStatus.doUpdateProjectStatus(bValue)
|
||||
self.projectStatusChanged.emit(self._projChanged)
|
||||
if bValue is True:
|
||||
# If we've changed the project at all, this should be True
|
||||
self._projAltered = True
|
||||
else:
|
||||
# If we're resetting the status, also reset for data class
|
||||
self._data.resetProjectChanged()
|
||||
return self._projChanged
|
||||
|
||||
##
|
||||
@@ -1310,3 +1310,301 @@ class NWProject:
|
||||
return True
|
||||
|
||||
# END Class NWProject
|
||||
|
||||
|
||||
class NWProjectData:
|
||||
|
||||
def __init__(self, theProject):
|
||||
|
||||
self.theProject = theProject
|
||||
|
||||
# Project Meta
|
||||
self._name = ""
|
||||
self._title = ""
|
||||
self._authors = []
|
||||
self._saveCount = 0
|
||||
self._autoCount = 0
|
||||
self._editTime = 0
|
||||
|
||||
# Project Settings
|
||||
self._doBackup = True
|
||||
self._language = None
|
||||
self._spellCheck = False
|
||||
self._spellLang = None
|
||||
self._lastHandle = {
|
||||
"editor": "",
|
||||
"viewer": "",
|
||||
"novelTree": "",
|
||||
"outline": "",
|
||||
}
|
||||
self._lastCount = {}
|
||||
self._currCount = {}
|
||||
|
||||
self._autoReplace = {}
|
||||
self._titleFormat = {
|
||||
"title": "%title%",
|
||||
"chapter": "%title%",
|
||||
"unnumbered": "%title%",
|
||||
"scene": "* * *",
|
||||
"section": "",
|
||||
}
|
||||
|
||||
self._status = NWStatus(NWStatus.STATUS)
|
||||
self._import = NWStatus(NWStatus.IMPORT)
|
||||
|
||||
return
|
||||
|
||||
##
|
||||
# Properties
|
||||
##
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def title(self):
|
||||
return self._title
|
||||
|
||||
@property
|
||||
def authors(self):
|
||||
return self._authors
|
||||
|
||||
@property
|
||||
def saveCount(self):
|
||||
return self._saveCount
|
||||
|
||||
@property
|
||||
def autoCount(self):
|
||||
return self._autoCount
|
||||
|
||||
@property
|
||||
def editTime(self):
|
||||
return self._editTime
|
||||
|
||||
@property
|
||||
def doBackup(self):
|
||||
return self._doBackup
|
||||
|
||||
@property
|
||||
def language(self):
|
||||
return self._language
|
||||
|
||||
@property
|
||||
def spellCheck(self):
|
||||
return self._spellCheck
|
||||
|
||||
@property
|
||||
def spellLang(self):
|
||||
return self._spellLang
|
||||
|
||||
@property
|
||||
def lastHandle(self):
|
||||
return self._lastHandle
|
||||
|
||||
@property
|
||||
def autoReplace(self):
|
||||
return self._autoReplace
|
||||
|
||||
@property
|
||||
def titleFormat(self):
|
||||
return self._titleFormat
|
||||
|
||||
@property
|
||||
def itemStatus(self):
|
||||
return self._status
|
||||
|
||||
@property
|
||||
def itemImport(self):
|
||||
return self._import
|
||||
|
||||
##
|
||||
# Methods
|
||||
##
|
||||
|
||||
def addAuthor(self, value):
|
||||
"""Add an author to the authors list.
|
||||
"""
|
||||
self._authors.append(simplified(str(value)))
|
||||
self.theProject.setProjectChanged(True)
|
||||
return
|
||||
|
||||
def incSaveCount(self):
|
||||
"""Increment the save count by one.
|
||||
"""
|
||||
self._saveCount += 1
|
||||
self.theProject.setProjectChanged(True)
|
||||
return
|
||||
|
||||
def incAutoCount(self):
|
||||
"""Increment the auto save count by one.
|
||||
"""
|
||||
self._autoCount += 1
|
||||
self.theProject.setProjectChanged(True)
|
||||
return
|
||||
|
||||
##
|
||||
# Getters
|
||||
##
|
||||
|
||||
def getLastHandle(self, component):
|
||||
"""Retrieve the last used handle for a given component.
|
||||
"""
|
||||
return self._lastHandle.get(component, None)
|
||||
|
||||
def getLastCount(self, type):
|
||||
"""Retrieve the last word count for a given type.
|
||||
"""
|
||||
return self._lastCount.get(type, 0)
|
||||
|
||||
def getCurrCount(self, type):
|
||||
"""Retrieve the current word count for a given type.
|
||||
"""
|
||||
return self._currCount.get(type, 0)
|
||||
|
||||
def getTitleFormat(self, kind):
|
||||
"""Retrieve the title format string for a given kind of header.
|
||||
"""
|
||||
return self._titleFormat.get(kind, "%title%")
|
||||
|
||||
##
|
||||
# Setters
|
||||
##
|
||||
|
||||
def setName(self, value):
|
||||
"""Set a new project name.
|
||||
"""
|
||||
if value != self._name:
|
||||
self._name = simplified(str(value))
|
||||
self.theProject.setProjectChanged(True)
|
||||
return
|
||||
|
||||
def setTitle(self, value):
|
||||
"""Set a new novel title.
|
||||
"""
|
||||
if value != self._title:
|
||||
self._title = simplified(str(value))
|
||||
self.theProject.setProjectChanged(True)
|
||||
return
|
||||
|
||||
def setAuthors(self, value):
|
||||
"""Set the list of authors from either a string with one author
|
||||
per line, or a list of authors.
|
||||
"""
|
||||
self._authors = []
|
||||
self.theProject.setProjectChanged(True)
|
||||
if isinstance(value, str):
|
||||
for author in value.splitlines():
|
||||
author = simplified(author)
|
||||
if author:
|
||||
self._authors.append(author)
|
||||
self.theProject.setProjectChanged(True)
|
||||
elif isinstance(value, list):
|
||||
self._authors = value
|
||||
return
|
||||
|
||||
def setSaveCount(self, value):
|
||||
"""Set the save count from last session.
|
||||
"""
|
||||
self._saveCount = checkInt(value, 0)
|
||||
self.theProject.setProjectChanged(True)
|
||||
return
|
||||
|
||||
def setAutoCount(self, value):
|
||||
"""Set the auto save count from last session.
|
||||
"""
|
||||
self._autoCount = checkInt(value, 0)
|
||||
self.theProject.setProjectChanged(True)
|
||||
return
|
||||
|
||||
def setEditTime(self, value):
|
||||
"""Set tyje edit time from last session.
|
||||
"""
|
||||
self._editTime = checkInt(value, 0)
|
||||
self.theProject.setProjectChanged(True)
|
||||
return
|
||||
|
||||
def setDoBackup(self, value):
|
||||
"""Set the do write backup flag.
|
||||
"""
|
||||
if value != self._doBackup:
|
||||
self._doBackup = checkBool(value, False)
|
||||
self.theProject.setProjectChanged(True)
|
||||
return
|
||||
|
||||
def setLanguage(self, value):
|
||||
"""Set the project language.
|
||||
"""
|
||||
if value != self._language:
|
||||
self._language = checkStringNone(value, None)
|
||||
self.theProject.setProjectChanged(True)
|
||||
return
|
||||
|
||||
def setSpellCheck(self, value):
|
||||
"""Set the spell check flag.
|
||||
"""
|
||||
if value != self._spellCheck:
|
||||
self._spellCheck = checkBool(value, False)
|
||||
self.theProject.setProjectChanged(True)
|
||||
return
|
||||
|
||||
def setSpellLang(self, value):
|
||||
"""Set the spell check language.
|
||||
"""
|
||||
if value != self._spellLang:
|
||||
self._spellLang = checkStringNone(value, None)
|
||||
self.theProject.setProjectChanged(True)
|
||||
return
|
||||
|
||||
def setLastHandle(self, value, component=None):
|
||||
"""Set a last used handle into the handle registry. If component
|
||||
is None, the value is assumed to be the whole dictionary of
|
||||
values.
|
||||
"""
|
||||
if isinstance(component, str):
|
||||
self._lastHandle[component] = checkString(value, "")
|
||||
self.theProject.setProjectChanged(True)
|
||||
elif isinstance(value, dict):
|
||||
for key, entry in value.items():
|
||||
if key in self._lastHandle:
|
||||
self._lastHandle[key] = checkString(entry, "")
|
||||
self.theProject.setProjectChanged(True)
|
||||
return
|
||||
|
||||
def setLastCount(self, value, type):
|
||||
"""Set the word counts from last session.
|
||||
"""
|
||||
self._lastCount[type] = checkInt(value, 0)
|
||||
self.theProject.setProjectChanged(True)
|
||||
return
|
||||
|
||||
def setCurrCount(self, value, type):
|
||||
"""Set the current word counts.
|
||||
"""
|
||||
if value != self._currCount.get(type, 0):
|
||||
self._currCount[type] = checkInt(value, 0)
|
||||
self.theProject.setProjectChanged(True)
|
||||
return
|
||||
|
||||
def setAutoReplace(self, value):
|
||||
"""Set the auto-replace dictionary.
|
||||
"""
|
||||
if isinstance(value, dict):
|
||||
self._autoReplace = {}
|
||||
for key, entry in value.items():
|
||||
if isinstance(entry, str):
|
||||
self._autoReplace[key] = simplified(entry)
|
||||
self.theProject.setProjectChanged(True)
|
||||
return
|
||||
|
||||
def setTitleFormat(self, value):
|
||||
"""Set the title formats.
|
||||
"""
|
||||
if isinstance(value, dict):
|
||||
for key, entry in value.items():
|
||||
if key in self._titleFormat and isinstance(entry, str):
|
||||
self._titleFormat[key] = simplified(entry)
|
||||
self.theProject.setProjectChanged(True)
|
||||
return
|
||||
|
||||
# END Class NWProjectData
|
||||
|
||||
@@ -1,271 +0,0 @@
|
||||
"""
|
||||
novelWriter – Project Data Class
|
||||
================================
|
||||
Class for holding the project settings
|
||||
|
||||
File History:
|
||||
Created: 2022-10-30 [2.0rc1]
|
||||
|
||||
This file is a part of novelWriter
|
||||
Copyright 2018–2022, Veronica Berglyd Olsen
|
||||
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
from novelwriter.common import (
|
||||
checkBool, checkInt, checkStringNone, simplified
|
||||
)
|
||||
from novelwriter.core.status import NWStatus
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class NWProjectData:
|
||||
|
||||
def __init__(self):
|
||||
|
||||
# Project Meta
|
||||
self._name = ""
|
||||
self._title = ""
|
||||
self._authors = []
|
||||
self._saveCount = 0
|
||||
self._autoCount = 0
|
||||
self._editTime = 0
|
||||
|
||||
# Project Settings
|
||||
self._doBackup = True
|
||||
self._language = None
|
||||
self._spellCheck = False
|
||||
self._spellLang = None
|
||||
self._lastHandle = {}
|
||||
self._lastCount = {}
|
||||
self._currCount = {}
|
||||
|
||||
self._autoReplace = {}
|
||||
self._titleFormat = {
|
||||
"title": "%title%",
|
||||
"chapter": "%title%",
|
||||
"unnumbered": "%title%",
|
||||
"scene": "* * *",
|
||||
"section": "",
|
||||
}
|
||||
|
||||
self._status = NWStatus(NWStatus.STATUS)
|
||||
self._import = NWStatus(NWStatus.IMPORT)
|
||||
|
||||
# Internal
|
||||
self._changed = False
|
||||
|
||||
return
|
||||
|
||||
##
|
||||
# Properties
|
||||
##
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def title(self):
|
||||
return self._title
|
||||
|
||||
@property
|
||||
def authors(self):
|
||||
return self._authors
|
||||
|
||||
@property
|
||||
def saveCount(self):
|
||||
return self._saveCount
|
||||
|
||||
@property
|
||||
def autoCount(self):
|
||||
return self._autoCount
|
||||
|
||||
@property
|
||||
def editTime(self):
|
||||
return self._editTime
|
||||
|
||||
@property
|
||||
def doBackup(self):
|
||||
return self._doBackup
|
||||
|
||||
@property
|
||||
def language(self):
|
||||
return self._language
|
||||
|
||||
@property
|
||||
def spellCheck(self):
|
||||
return self._spellCheck
|
||||
|
||||
@property
|
||||
def spellLang(self):
|
||||
return self._spellLang
|
||||
|
||||
@property
|
||||
def autoReplace(self):
|
||||
return self._autoReplace
|
||||
|
||||
@property
|
||||
def titleFormat(self):
|
||||
return self._titleFormat
|
||||
|
||||
@property
|
||||
def itemStatus(self):
|
||||
return self._status
|
||||
|
||||
@property
|
||||
def itemImport(self):
|
||||
return self._import
|
||||
|
||||
@property
|
||||
def changed(self):
|
||||
return self._changed
|
||||
|
||||
##
|
||||
# Methods
|
||||
##
|
||||
|
||||
def addAuthor(self, value):
|
||||
self._authors.append(simplified(str(value)))
|
||||
self._changed = True
|
||||
return
|
||||
|
||||
def incSaveCount(self):
|
||||
self._saveCount += 1
|
||||
self._changed = True
|
||||
return
|
||||
|
||||
def incAutoCount(self):
|
||||
self._autoCount += 1
|
||||
self._changed = True
|
||||
return
|
||||
|
||||
def resetProjectChanged(self):
|
||||
self._changed = False
|
||||
|
||||
##
|
||||
# Getters
|
||||
##
|
||||
|
||||
def getLastHandle(self, component):
|
||||
return self._lastHandle.get(component, None)
|
||||
|
||||
def getLastCount(self, type):
|
||||
return self._lastCount.get(type, 0)
|
||||
|
||||
def getCurrCount(self, type):
|
||||
return self._currCount.get(type, 0)
|
||||
|
||||
def getTitleFormat(self, kind):
|
||||
return self._titleFormat.get(kind, "%title%")
|
||||
|
||||
##
|
||||
# Setters
|
||||
##
|
||||
|
||||
def setName(self, value):
|
||||
self._name = simplified(str(value))
|
||||
self._changed = True
|
||||
return
|
||||
|
||||
def setTitle(self, value):
|
||||
self._title = simplified(str(value))
|
||||
self._changed = True
|
||||
return
|
||||
|
||||
def setAuthors(self, value):
|
||||
self._authors = []
|
||||
self._changed = True
|
||||
if isinstance(value, str):
|
||||
for author in value.splitlines():
|
||||
author = simplified(author)
|
||||
if author:
|
||||
self._authors.append(author)
|
||||
self._changed = True
|
||||
elif isinstance(value, list):
|
||||
self._authors = value
|
||||
return
|
||||
|
||||
def setSaveCount(self, value):
|
||||
self._saveCount = checkInt(value, 0)
|
||||
self._changed = True
|
||||
return
|
||||
|
||||
def setAutoCount(self, value):
|
||||
self._autoCount = checkInt(value, 0)
|
||||
self._changed = True
|
||||
return
|
||||
|
||||
def setEditTime(self, value):
|
||||
self._editTime = checkInt(value, 0)
|
||||
self._changed = True
|
||||
return
|
||||
|
||||
def setDoBackup(self, value):
|
||||
self._doBackup = checkBool(value, False)
|
||||
self._changed = True
|
||||
return
|
||||
|
||||
def setLanguage(self, value):
|
||||
self._language = checkStringNone(value, None)
|
||||
self._changed = True
|
||||
return
|
||||
|
||||
def setSpellCheck(self, value):
|
||||
self._spellCheck = checkBool(value, False)
|
||||
self._changed = True
|
||||
return
|
||||
|
||||
def setSpellLang(self, value):
|
||||
self._spellLang = checkStringNone(value, None)
|
||||
self._changed = True
|
||||
return
|
||||
|
||||
def setLastHandle(self, value, component):
|
||||
self._lastHandle[component] = checkStringNone(value, None)
|
||||
self._changed = True
|
||||
return
|
||||
|
||||
def setLastCount(self, value, type):
|
||||
self._lastCount[type] = checkInt(value, 0)
|
||||
self._changed = True
|
||||
return
|
||||
|
||||
def setCurrCount(self, value, type):
|
||||
if value != self._currCount.get(type, 0):
|
||||
self._currCount[type] = checkInt(value, 0)
|
||||
self._changed = True
|
||||
return
|
||||
|
||||
def setAutoReplace(self, value):
|
||||
if isinstance(value, dict):
|
||||
self._autoReplace = {}
|
||||
for key, entry in value.items():
|
||||
if isinstance(entry, str):
|
||||
self._autoReplace[key] = simplified(entry)
|
||||
self._changed = True
|
||||
return
|
||||
|
||||
def setTitleFormat(self, value):
|
||||
if isinstance(value, dict):
|
||||
for key, entry in value.items():
|
||||
if key in self._titleFormat and isinstance(entry, str):
|
||||
self._titleFormat[key] = simplified(entry)
|
||||
self._changed = True
|
||||
return
|
||||
|
||||
# END Class NWProjectData
|
||||
@@ -266,14 +266,10 @@ class ProjectXMLReader:
|
||||
projData.setSpellCheck(xItem.text)
|
||||
elif xItem.tag == "spellLang":
|
||||
projData.setSpellLang(xItem.text)
|
||||
elif xItem.tag == "lastEdited":
|
||||
elif xItem.tag == "lastEdited": # Discontinued in 1.4
|
||||
projData.setLastHandle(xItem.text, "editor")
|
||||
elif xItem.tag == "lastViewed":
|
||||
elif xItem.tag == "lastViewed": # Discontinued in 1.4
|
||||
projData.setLastHandle(xItem.text, "viewer")
|
||||
elif xItem.tag == "lastNovel":
|
||||
projData.setLastHandle(xItem.text, "noveltree")
|
||||
elif xItem.tag == "lastOutline":
|
||||
projData.setLastHandle(xItem.text, "outline")
|
||||
elif xItem.tag == "lastWordCount":
|
||||
projData.setLastCount(xItem.text, "total")
|
||||
elif xItem.tag == "novelWordCount":
|
||||
@@ -284,9 +280,11 @@ class ProjectXMLReader:
|
||||
self._parseStatusImport(xItem, projData.itemStatus)
|
||||
elif xItem.tag in ("import", "importance"):
|
||||
self._parseStatusImport(xItem, projData.itemImport)
|
||||
elif xItem.tag == "lastHandle":
|
||||
projData.setLastHandle(self._parseDictKeyText(xItem, "component"))
|
||||
elif xItem.tag == "autoReplace":
|
||||
if self._version >= 0x0102:
|
||||
projData.setAutoReplace(self._parseDictKeyText(xItem))
|
||||
projData.setAutoReplace(self._parseDictKeyText(xItem, "key"))
|
||||
else: # Pre 1.2 format
|
||||
projData.setAutoReplace(self._parseDictTagText(xItem))
|
||||
elif xItem.tag == "titleFormat":
|
||||
@@ -304,13 +302,13 @@ class ProjectXMLReader:
|
||||
for xItem in xSection:
|
||||
if xItem.tag == "item":
|
||||
item = {}
|
||||
item["handle"] = xItem.attrib.get("handle", None)
|
||||
item["parent"] = xItem.attrib.get("parent", None)
|
||||
item["root"] = xItem.attrib.get("root", None)
|
||||
item["handle"] = checkStringNone(xItem.attrib.get("handle", None), None)
|
||||
item["parent"] = checkStringNone(xItem.attrib.get("parent", None), None)
|
||||
item["root"] = checkStringNone(xItem.attrib.get("root", None), None)
|
||||
item["order"] = checkInt(xItem.attrib.get("order", 0), 0)
|
||||
item["type"] = checkString(xItem.attrib.get("type", ""), "")
|
||||
item["class"] = checkString(xItem.attrib.get("class", ""), "")
|
||||
item["layout"] = checkString(xItem.attrib.get("layout", ""), "")
|
||||
item["type"] = checkString(xItem.attrib.get("type", "NO_TYPE"), "NO_TYPE")
|
||||
item["class"] = checkString(xItem.attrib.get("class", "NO_CLASS"), "NO_CLASS")
|
||||
item["layout"] = checkString(xItem.attrib.get("layout", "NO_LAYOUT"), "NO_LAYOUT")
|
||||
for xVal in xItem:
|
||||
if xVal.tag == "meta":
|
||||
item["expanded"] = checkBool(xVal.attrib.get("expanded", False), False)
|
||||
@@ -339,7 +337,7 @@ class ProjectXMLReader:
|
||||
return True
|
||||
|
||||
def _parseProjectContentLegacy(self, xSection):
|
||||
"""Parse the content section of the XML file for older version.
|
||||
"""Parse the content section of the XML file for older versions.
|
||||
"""
|
||||
logger.debug("Parsing xml <root/content> (legacy format)")
|
||||
depLayout = ("TITLE", "PAGE", "BOOK", "PARTITION", "UNNUMBERED", "CHAPTER", "SCENE")
|
||||
@@ -347,8 +345,8 @@ class ProjectXMLReader:
|
||||
for xItem in xSection:
|
||||
item = {}
|
||||
if xItem.tag == "item":
|
||||
item["handle"] = xItem.attrib.get("handle", None)
|
||||
item["parent"] = xItem.attrib.get("parent", None)
|
||||
item["handle"] = checkStringNone(xItem.attrib.get("handle", None), None)
|
||||
item["parent"] = checkStringNone(xItem.attrib.get("parent", None), None)
|
||||
item["root"] = None # Value was added in 1.4
|
||||
item["order"] = checkInt(xItem.attrib.get("order", 0), 0)
|
||||
item["heading"] = "H0" # Value was added in 1.4
|
||||
@@ -421,14 +419,14 @@ class ProjectXMLReader:
|
||||
self._importMap = {entry["name"]: key for key, entry in projData.itemImport.items()}
|
||||
return
|
||||
|
||||
def _parseDictKeyText(self, xItem):
|
||||
def _parseDictKeyText(self, xItem, keyName):
|
||||
"""Parse a dictionary stored with key as an attribute and the
|
||||
value as the text porperty.
|
||||
"""
|
||||
result = {}
|
||||
for xEntry in xItem:
|
||||
if xEntry.tag == "entry" and "key" in xEntry.attrib:
|
||||
result[xEntry.attrib["key"]] = checkString(xEntry.text, "")
|
||||
if xEntry.tag == "entry" and keyName in xEntry.attrib:
|
||||
result[xEntry.attrib[keyName]] = checkString(xEntry.text, "")
|
||||
return result
|
||||
|
||||
def _parseDictTagText(self, xItem):
|
||||
@@ -473,14 +471,11 @@ class ProjectXMLWriter:
|
||||
self._packSingleValue(xSettings, "language", projData.language)
|
||||
self._packSingleValue(xSettings, "spellCheck", projData.spellCheck)
|
||||
self._packSingleValue(xSettings, "spellLang", projData.spellLang)
|
||||
self._packSingleValue(xSettings, "lastEdited", projData.getLastHandle("editor"))
|
||||
self._packSingleValue(xSettings, "lastViewed", projData.getLastHandle("viewer"))
|
||||
self._packSingleValue(xSettings, "lastNovel", projData.getLastHandle("noveltree"))
|
||||
self._packSingleValue(xSettings, "lastOutline", projData.getLastHandle("outline"))
|
||||
self._packSingleValue(xSettings, "lastWordCount", projData.getCurrCount("total"))
|
||||
self._packSingleValue(xSettings, "novelWordCount", projData.getCurrCount("novel"))
|
||||
self._packSingleValue(xSettings, "notesWordCount", projData.getCurrCount("notes"))
|
||||
self._packDictKeyValue(xSettings, "autoReplace", projData.autoReplace)
|
||||
self._packDictKeyValue(xSettings, "lastHandle", projData.lastHandle, "component")
|
||||
self._packDictKeyValue(xSettings, "autoReplace", projData.autoReplace, "key")
|
||||
self._packDictTagValue(xSettings, "titleFormat", projData.titleFormat)
|
||||
|
||||
# Save Status/Importance
|
||||
@@ -549,14 +544,15 @@ class ProjectXMLWriter:
|
||||
self._packSingleValue(xParent, name, value, allowNone=allowNone)
|
||||
return
|
||||
|
||||
def _packDictKeyValue(self, xParent, name, data):
|
||||
def _packDictKeyValue(self, xParent, name, data, keyName):
|
||||
"""Pack the entries of a dictionary into an xml element.
|
||||
"""
|
||||
xItem = etree.SubElement(xParent, name)
|
||||
for key, value in data.items():
|
||||
if len(key) > 0:
|
||||
xEntry = etree.SubElement(xItem, "entry", attrib={"key": key})
|
||||
xEntry.text = value
|
||||
xEntry = etree.SubElement(xItem, "entry", attrib={keyName: key})
|
||||
if value:
|
||||
xEntry.text = value
|
||||
return
|
||||
|
||||
def _packDictTagValue(self, xParent, name, data):
|
||||
|
||||
@@ -109,7 +109,7 @@ class GuiNovelView(QWidget):
|
||||
def refreshTree(self):
|
||||
"""Refresh the current tree.
|
||||
"""
|
||||
self.novelTree.refreshTree(rootHandle=self.theProject.data.getLastHandle("noveltree"))
|
||||
self.novelTree.refreshTree(rootHandle=self.theProject.data.getLastHandle("novelTree"))
|
||||
return
|
||||
|
||||
def clearProject(self):
|
||||
@@ -122,7 +122,7 @@ class GuiNovelView(QWidget):
|
||||
def openProjectTasks(self):
|
||||
"""Run open project tasks.
|
||||
"""
|
||||
lastNovel = self.theProject.data.getLastHandle("noveltree")
|
||||
lastNovel = self.theProject.data.getLastHandle("novelTree")
|
||||
if lastNovel not in self.theProject.tree:
|
||||
lastNovel = self.theProject.tree.findRoot(nwItemClass.NOVEL)
|
||||
|
||||
@@ -319,7 +319,7 @@ class GuiNovelToolBar(QWidget):
|
||||
def _refreshNovelTree(self):
|
||||
"""Rebuild the current tree.
|
||||
"""
|
||||
rootHandle = self.theProject.data.getLastHandle("noveltree")
|
||||
rootHandle = self.theProject.data.getLastHandle("novelTree")
|
||||
self.novelView.novelTree.refreshTree(rootHandle=rootHandle, overRide=True)
|
||||
return
|
||||
|
||||
@@ -485,7 +485,7 @@ class GuiNovelTree(QTreeWidget):
|
||||
titleKey = selItem[0].data(self.C_TITLE, self.D_KEY)
|
||||
|
||||
self._populateTree(rootHandle)
|
||||
self.theProject.data.setLastHandle(rootHandle, "noveltree")
|
||||
self.theProject.data.setLastHandle(rootHandle, "novelTree")
|
||||
|
||||
if titleKey is not None and titleKey in self._treeMap:
|
||||
self._treeMap[titleKey].setSelected(True)
|
||||
@@ -523,7 +523,7 @@ class GuiNovelTree(QTreeWidget):
|
||||
self._lastCol = colType
|
||||
self.setColumnHidden(self.C_EXTRA, colType == NovelTreeColumn.HIDDEN)
|
||||
if doRefresh:
|
||||
lastNovel = self.theProject.data.getLastHandle("noveltree")
|
||||
lastNovel = self.theProject.data.getLastHandle("novelTree")
|
||||
self.refreshTree(rootHandle=lastNovel, overRide=True)
|
||||
return
|
||||
|
||||
|
||||
@@ -197,6 +197,8 @@ class GuiMain(QMainWindow):
|
||||
# Connect Signals
|
||||
# ===============
|
||||
|
||||
self.theProject.projectStatusChanged.connect(self.mainStatus.doUpdateProjectStatus)
|
||||
|
||||
self.viewsBar.viewChangeRequested.connect(self._changeView)
|
||||
|
||||
self.projView.selectedItemChanged.connect(self.itemDetails.updateViewBox)
|
||||
|
||||
@@ -1,26 +1,28 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<novelWriterXML appVersion="2.0-rc1" hexVersion="0x020000c1" fileVersion="1.4" timeStamp="2022-10-31 18:11:11">
|
||||
<novelWriterXML appVersion="2.0-rc1" hexVersion="0x020000c1" fileVersion="1.4" timeStamp="2022-10-31 21:24:31">
|
||||
<project>
|
||||
<name>Sample Project</name>
|
||||
<title>Sample Project</title>
|
||||
<author>Jane Smith</author>
|
||||
<author>Jay Doh</author>
|
||||
<saveCount>1387</saveCount>
|
||||
<saveCount>1403</saveCount>
|
||||
<autoCount>236</autoCount>
|
||||
<editTime>69358</editTime>
|
||||
<editTime>69454</editTime>
|
||||
</project>
|
||||
<settings>
|
||||
<doBackup>False</doBackup>
|
||||
<language>en_GB</language>
|
||||
<spellCheck>True</spellCheck>
|
||||
<spellLang>None</spellLang>
|
||||
<lastEdited>636b6aa9b697b</lastEdited>
|
||||
<lastViewed>636b6aa9b697b</lastViewed>
|
||||
<lastNovel>7031beac91f75</lastNovel>
|
||||
<lastOutline>7031beac91f75</lastOutline>
|
||||
<lastWordCount>1363</lastWordCount>
|
||||
<novelWordCount>954</novelWordCount>
|
||||
<notesWordCount>409</notesWordCount>
|
||||
<lastHandle>
|
||||
<entry component="editor">636b6aa9b697b</entry>
|
||||
<entry component="viewer">636b6aa9b697b</entry>
|
||||
<entry component="novelTree">7031beac91f75</entry>
|
||||
<entry component="outline">7031beac91f75</entry>
|
||||
</lastHandle>
|
||||
<autoReplace>
|
||||
<entry key="A">B</entry>
|
||||
<entry key="B">E</entry>
|
||||
|
||||
Reference in New Issue
Block a user