Update new project creation (#1067)
This commit is contained in:
+58
-52
@@ -120,32 +120,34 @@ class NWProject():
|
||||
# Item Methods
|
||||
##
|
||||
|
||||
def newRoot(self, rootName, rootClass):
|
||||
"""Add a new root item.
|
||||
def newRoot(self, itemClass, label=None):
|
||||
"""Add a new root item. If label is None, use the class label.
|
||||
"""
|
||||
if label is None:
|
||||
label = trConst(nwLabels.CLASS_NAME[itemClass])
|
||||
newItem = NWItem(self)
|
||||
newItem.setName(rootName)
|
||||
newItem.setName(label)
|
||||
newItem.setType(nwItemType.ROOT)
|
||||
newItem.setClass(rootClass)
|
||||
newItem.setClass(itemClass)
|
||||
self.projTree.append(None, None, newItem)
|
||||
self.projTree.updateItemData(newItem.itemHandle)
|
||||
return newItem.itemHandle
|
||||
|
||||
def newFolder(self, folderName, pHandle):
|
||||
"""Add a new folder with a given name and parent item.
|
||||
def newFolder(self, label, pHandle):
|
||||
"""Add a new folder with a given label and parent item.
|
||||
"""
|
||||
newItem = NWItem(self)
|
||||
newItem.setName(folderName)
|
||||
newItem.setName(label)
|
||||
newItem.setType(nwItemType.FOLDER)
|
||||
self.projTree.append(None, pHandle, newItem)
|
||||
self.projTree.updateItemData(newItem.itemHandle)
|
||||
return newItem.itemHandle
|
||||
|
||||
def newFile(self, fileName, pHandle):
|
||||
"""Add a new file with a given name and parent item.
|
||||
def newFile(self, label, pHandle):
|
||||
"""Add a new file with a given label and parent item.
|
||||
"""
|
||||
newItem = NWItem(self)
|
||||
newItem.setName(fileName)
|
||||
newItem.setName(label)
|
||||
newItem.setType(nwItemType.FILE)
|
||||
self.projTree.append(None, pHandle, newItem)
|
||||
self.projTree.updateItemData(newItem.itemHandle)
|
||||
@@ -264,84 +266,88 @@ class NWProject():
|
||||
self.setBookTitle(projTitle)
|
||||
self.setBookAuthors(projAuthors)
|
||||
|
||||
hNovelRoot = self.newRoot(nwItemClass.NOVEL)
|
||||
hTitlePage = self.newFile(self.tr("Title Page"), hNovelRoot)
|
||||
|
||||
titlePage = "#! %s\n\n" % (self.bookTitle if self.bookTitle else self.projName)
|
||||
if self.bookAuthors:
|
||||
titlePage = "%s>> %s %s <<\n" % (titlePage, self.tr("By"), self.getAuthors())
|
||||
|
||||
aDoc = NWDoc(self, hTitlePage)
|
||||
aDoc.writeDocument(titlePage)
|
||||
|
||||
if popMinimal:
|
||||
# Creating a minimal project with a few root folders and a
|
||||
# single chapter folder with a single file.
|
||||
xHandle = {}
|
||||
xHandle[1] = self.newRoot(self.tr("Novel"), nwItemClass.NOVEL)
|
||||
xHandle[2] = self.newRoot(self.tr("Plot"), nwItemClass.PLOT)
|
||||
xHandle[3] = self.newRoot(self.tr("Characters"), nwItemClass.CHARACTER)
|
||||
xHandle[4] = self.newRoot(self.tr("World"), nwItemClass.WORLD)
|
||||
xHandle[5] = self.newFile(self.tr("Title Page"), xHandle[1])
|
||||
xHandle[6] = self.newFolder(self.tr("New Chapter"), xHandle[1])
|
||||
xHandle[7] = self.newFile(self.tr("New Chapter"), xHandle[6])
|
||||
xHandle[8] = self.newFile(self.tr("New Scene"), xHandle[6])
|
||||
|
||||
aDoc = NWDoc(self, xHandle[5])
|
||||
aDoc.writeDocument(titlePage)
|
||||
|
||||
aDoc = NWDoc(self, xHandle[7])
|
||||
# single chapter with a single scene.
|
||||
hChapter = self.newFile(self.tr("New Chapter"), hNovelRoot)
|
||||
aDoc = NWDoc(self, hChapter)
|
||||
aDoc.writeDocument("## %s\n\n" % self.tr("New Chapter"))
|
||||
|
||||
aDoc = NWDoc(self, xHandle[8])
|
||||
hScene = self.newFile(self.tr("New Scene"), hChapter)
|
||||
aDoc = NWDoc(self, hScene)
|
||||
aDoc.writeDocument("### %s\n\n" % self.tr("New Scene"))
|
||||
|
||||
self.newRoot(nwItemClass.PLOT)
|
||||
self.newRoot(nwItemClass.CHARACTER)
|
||||
self.newRoot(nwItemClass.WORLD)
|
||||
self.newRoot(nwItemClass.ARCHIVE)
|
||||
|
||||
elif popCustom:
|
||||
# Create a project structure based on selected root folders
|
||||
# and a number of chapters and scenes selected in the
|
||||
# wizard's custom page.
|
||||
|
||||
# Create root folders
|
||||
nHandle = self.newRoot(self.tr("Novel"), nwItemClass.NOVEL)
|
||||
for newRoot in projData.get("addRoots", []):
|
||||
if newRoot in nwItemClass:
|
||||
self.newRoot(trConst(nwLabels.CLASS_NAME[newRoot]), newRoot)
|
||||
|
||||
# Create a title page
|
||||
tHandle = self.newFile(self.tr("Title Page"), nHandle)
|
||||
|
||||
aDoc = NWDoc(self, tHandle)
|
||||
aDoc.writeDocument(titlePage)
|
||||
|
||||
# Create chapters and scenes
|
||||
numChapters = projData.get("numChapters", 0)
|
||||
numScenes = projData.get("numScenes", 0)
|
||||
chFolders = projData.get("chFolders", False)
|
||||
|
||||
chSynop = self.tr("Summary of the chapter.")
|
||||
scSynop = self.tr("Summary of the scene.")
|
||||
|
||||
# Create chapters
|
||||
if numChapters > 0:
|
||||
for ch in range(numChapters):
|
||||
chTitle = self.tr("Chapter {0}").format(f"{ch+1:d}")
|
||||
pHandle = nHandle
|
||||
if chFolders:
|
||||
pHandle = self.newFolder(chTitle, nHandle)
|
||||
|
||||
cHandle = self.newFile(chTitle, pHandle)
|
||||
|
||||
cHandle = self.newFile(chTitle, hNovelRoot)
|
||||
aDoc = NWDoc(self, cHandle)
|
||||
aDoc.writeDocument("## %s\n\n" % chTitle)
|
||||
aDoc.writeDocument(f"## {chTitle}\n\n% Synopsis: {chSynop}\n\n")
|
||||
|
||||
# Create chapter scenes
|
||||
if numScenes > 0:
|
||||
for sc in range(numScenes):
|
||||
scTitle = self.tr("Scene {0}").format(f"{ch+1:d}.{sc+1:d}")
|
||||
sHandle = self.newFile(scTitle, pHandle)
|
||||
|
||||
sHandle = self.newFile(scTitle, cHandle)
|
||||
aDoc = NWDoc(self, sHandle)
|
||||
aDoc.writeDocument("### %s\n\n" % scTitle)
|
||||
aDoc.writeDocument(f"### {scTitle}\n\n% Synopsis: {scSynop}\n\n")
|
||||
|
||||
# Create scenes (no chapters)
|
||||
elif numScenes > 0:
|
||||
for sc in range(numScenes):
|
||||
scTitle = self.tr("Scene {0}").format(f"{sc+1:d}")
|
||||
sHandle = self.newFile(scTitle, nHandle)
|
||||
|
||||
sHandle = self.newFile(scTitle, hNovelRoot)
|
||||
aDoc = NWDoc(self, sHandle)
|
||||
aDoc.writeDocument("### %s\n\n" % scTitle)
|
||||
aDoc.writeDocument(f"### {scTitle}\n\n% Synopsis: {scSynop}\n\n")
|
||||
|
||||
# Create notes folders
|
||||
noteTitles = {
|
||||
nwItemClass.PLOT: self.tr("Main Plot"),
|
||||
nwItemClass.CHARACTER: self.tr("Protagonist"),
|
||||
nwItemClass.WORLD: self.tr("Main Location"),
|
||||
}
|
||||
|
||||
addNotes = projData.get("addNotes", False)
|
||||
for newRoot in projData.get("addRoots", []):
|
||||
if newRoot in nwItemClass:
|
||||
rHandle = self.newRoot(newRoot)
|
||||
if addNotes:
|
||||
aHandle = self.newFile(noteTitles[newRoot], rHandle)
|
||||
ntTag = simplified(noteTitles[newRoot]).replace(" ", "")
|
||||
aDoc = NWDoc(self, aHandle)
|
||||
aDoc.writeDocument(f"# {noteTitles[newRoot]}\n\n@tag: {ntTag}\n\n")
|
||||
|
||||
# Also add the archive and trash folders
|
||||
self.newRoot(nwItemClass.ARCHIVE)
|
||||
self.trashFolder()
|
||||
|
||||
# Finalise
|
||||
if popCustom or popMinimal:
|
||||
|
||||
@@ -37,7 +37,6 @@ from PyQt5.QtWidgets import (
|
||||
|
||||
from novelwriter.core import NWDoc
|
||||
from novelwriter.enum import nwItemType, nwItemClass, nwItemLayout, nwAlert
|
||||
from novelwriter.constants import trConst, nwLabels
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -176,9 +175,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
|
||||
if itemType == nwItemType.ROOT and isinstance(itemClass, nwItemClass):
|
||||
|
||||
tHandle = self.theProject.newRoot(
|
||||
trConst(nwLabels.CLASS_NAME[itemClass]), itemClass
|
||||
)
|
||||
tHandle = self.theProject.newRoot(itemClass)
|
||||
|
||||
elif itemType in (nwItemType.FILE, nwItemType.FOLDER):
|
||||
|
||||
|
||||
@@ -1440,9 +1440,9 @@ class GuiMain(QMainWindow):
|
||||
"popMinimal": newProj.field("popMinimal"),
|
||||
"popCustom": newProj.field("popCustom"),
|
||||
"addRoots": [],
|
||||
"addNotes": False,
|
||||
"numChapters": 0,
|
||||
"numScenes": 0,
|
||||
"chFolders": False,
|
||||
}
|
||||
if newProj.field("popCustom"):
|
||||
addRoots = []
|
||||
@@ -1452,16 +1452,10 @@ class GuiMain(QMainWindow):
|
||||
addRoots.append(nwItemClass.CHARACTER)
|
||||
if newProj.field("addWorld"):
|
||||
addRoots.append(nwItemClass.WORLD)
|
||||
if newProj.field("addTime"):
|
||||
addRoots.append(nwItemClass.TIMELINE)
|
||||
if newProj.field("addObject"):
|
||||
addRoots.append(nwItemClass.OBJECT)
|
||||
if newProj.field("addEntity"):
|
||||
addRoots.append(nwItemClass.ENTITY)
|
||||
projData["addRoots"] = addRoots
|
||||
projData["addNotes"] = newProj.field("addNotes")
|
||||
projData["numChapters"] = newProj.field("numChapters")
|
||||
projData["numScenes"] = newProj.field("numScenes")
|
||||
projData["chFolders"] = newProj.field("chFolders")
|
||||
|
||||
return projData
|
||||
|
||||
|
||||
@@ -31,12 +31,10 @@ from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtWidgets import (
|
||||
QWizard, QWizardPage, QLabel, QVBoxLayout, QLineEdit, QPlainTextEdit,
|
||||
QPushButton, QFileDialog, QHBoxLayout, QRadioButton, QFormLayout,
|
||||
QGroupBox, QGridLayout, QSpinBox
|
||||
QGridLayout, QSpinBox
|
||||
)
|
||||
|
||||
from novelwriter.enum import nwItemClass
|
||||
from novelwriter.common import makeFileNameSafe
|
||||
from novelwriter.constants import trConst, nwLabels
|
||||
from novelwriter.gui.custom import QSwitch
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -98,10 +96,10 @@ class ProjWizardIntroPage(QWizardPage):
|
||||
|
||||
self.setTitle(self.tr("Create New Project"))
|
||||
self.theText = QLabel(self.tr(
|
||||
"Provide at least a working title. The working title should not "
|
||||
"be change beyond this point as it is used by the application for "
|
||||
"generating file names for for instance backups. The other fields "
|
||||
"are optional and can be changed at any time in Project Settings."
|
||||
"Provide at least a project name. The project name should not "
|
||||
"be changed beyond this point as it is used for generating file "
|
||||
"names for for instance backups. The other fields are optional "
|
||||
"and can be changed at any time in Project Settings."
|
||||
))
|
||||
self.theText.setWordWrap(True)
|
||||
|
||||
@@ -134,7 +132,7 @@ class ProjWizardIntroPage(QWizardPage):
|
||||
self.projAuthors.setPlaceholderText(self.tr("Optional. One name per line."))
|
||||
|
||||
self.mainForm = QFormLayout()
|
||||
self.mainForm.addRow(self.tr("Working Title"), self.projName)
|
||||
self.mainForm.addRow(self.tr("Project Name"), self.projName)
|
||||
self.mainForm.addRow(self.tr("Novel Title"), self.projTitle)
|
||||
self.mainForm.addRow(self.tr("Author(s)"), self.projAuthors)
|
||||
self.mainForm.setVerticalSpacing(fS)
|
||||
@@ -324,68 +322,28 @@ class ProjWizardCustomPage(QWizardPage):
|
||||
|
||||
self.setTitle(self.tr("Custom Project Options"))
|
||||
self.theText = QLabel(self.tr(
|
||||
"Select which additional root folders to make, and how to populate "
|
||||
"the Novel folder. If you don't want to add chapters or scenes, set "
|
||||
"the values to 0. You can add scenes without chapters."
|
||||
"Select which additional elements to populate the project with. "
|
||||
"You can skip making chapters and add only scenes by setting the "
|
||||
"number of chapters to 0."
|
||||
))
|
||||
self.theText.setWordWrap(True)
|
||||
|
||||
vS = self.mainConf.pxInt(12)
|
||||
cM = self.mainConf.pxInt(12)
|
||||
mH = self.mainConf.pxInt(26)
|
||||
fS = self.mainConf.pxInt(4)
|
||||
|
||||
# Root Folders
|
||||
self.rootGroup = QGroupBox(self.tr("Additional Root Folders"))
|
||||
self.rootForm = QGridLayout()
|
||||
self.rootGroup.setLayout(self.rootForm)
|
||||
|
||||
self.lblPlot = QLabel(self.tr("{0} folder").format(
|
||||
trConst(nwLabels.CLASS_NAME[nwItemClass.PLOT]))
|
||||
)
|
||||
self.lblChar = QLabel(self.tr("{0} folder").format(
|
||||
trConst(nwLabels.CLASS_NAME[nwItemClass.CHARACTER]))
|
||||
)
|
||||
self.lblWorld = QLabel(self.tr("{0} folder").format(
|
||||
trConst(nwLabels.CLASS_NAME[nwItemClass.WORLD]))
|
||||
)
|
||||
self.lblTime = QLabel(self.tr("{0} folder").format(
|
||||
trConst(nwLabels.CLASS_NAME[nwItemClass.TIMELINE]))
|
||||
)
|
||||
self.lblObject = QLabel(self.tr("{0} folder").format(
|
||||
trConst(nwLabels.CLASS_NAME[nwItemClass.OBJECT]))
|
||||
)
|
||||
self.lblEntity = QLabel(self.tr("{0} folder").format(
|
||||
trConst(nwLabels.CLASS_NAME[nwItemClass.ENTITY]))
|
||||
)
|
||||
|
||||
self.addPlot = QSwitch()
|
||||
self.addChar = QSwitch()
|
||||
self.addWorld = QSwitch()
|
||||
self.addTime = QSwitch()
|
||||
self.addObject = QSwitch()
|
||||
self.addEntity = QSwitch()
|
||||
self.addPlot = QSwitch()
|
||||
self.addChar = QSwitch()
|
||||
self.addWorld = QSwitch()
|
||||
self.addNotes = QSwitch()
|
||||
|
||||
self.addPlot.setChecked(True)
|
||||
self.addChar.setChecked(True)
|
||||
self.addWorld.setChecked(True)
|
||||
|
||||
self.rootForm.addWidget(self.lblPlot, 0, 0)
|
||||
self.rootForm.addWidget(self.lblChar, 1, 0)
|
||||
self.rootForm.addWidget(self.lblWorld, 2, 0)
|
||||
self.rootForm.addWidget(self.lblTime, 3, 0)
|
||||
self.rootForm.addWidget(self.lblObject, 4, 0)
|
||||
self.rootForm.addWidget(self.lblEntity, 5, 0)
|
||||
self.rootForm.addWidget(self.addPlot, 0, 1, 1, 1, Qt.AlignRight)
|
||||
self.rootForm.addWidget(self.addChar, 1, 1, 1, 1, Qt.AlignRight)
|
||||
self.rootForm.addWidget(self.addWorld, 2, 1, 1, 1, Qt.AlignRight)
|
||||
self.rootForm.addWidget(self.addTime, 3, 1, 1, 1, Qt.AlignRight)
|
||||
self.rootForm.addWidget(self.addObject, 4, 1, 1, 1, Qt.AlignRight)
|
||||
self.rootForm.addWidget(self.addEntity, 5, 1, 1, 1, Qt.AlignRight)
|
||||
self.rootForm.setRowStretch(6, 1)
|
||||
|
||||
# Novel Options
|
||||
self.novelGroup = QGroupBox(self.tr("Populate Novel Folder"))
|
||||
self.novelForm = QGridLayout()
|
||||
self.novelGroup.setLayout(self.novelForm)
|
||||
self.addWorld.setChecked(False)
|
||||
self.addNotes.setChecked(False)
|
||||
|
||||
# Generate Content
|
||||
self.numChapters = QSpinBox()
|
||||
self.numChapters.setRange(0, 100)
|
||||
self.numChapters.setValue(5)
|
||||
@@ -394,37 +352,40 @@ class ProjWizardCustomPage(QWizardPage):
|
||||
self.numScenes.setRange(0, 200)
|
||||
self.numScenes.setValue(5)
|
||||
|
||||
self.chFolders = QSwitch()
|
||||
self.chFolders.setChecked(True)
|
||||
|
||||
self.novelForm.addWidget(QLabel(self.tr("Add chapters")), 0, 0)
|
||||
self.novelForm.addWidget(QLabel(self.tr("Scenes (per chapter)")), 1, 0)
|
||||
self.novelForm.addWidget(QLabel(self.tr("Add chapter folders")), 2, 0)
|
||||
self.novelForm.addWidget(self.numChapters, 0, 1, 1, 1, Qt.AlignRight)
|
||||
self.novelForm.addWidget(self.numScenes, 1, 1, 1, 1, Qt.AlignRight)
|
||||
self.novelForm.addWidget(self.chFolders, 2, 1, 1, 1, Qt.AlignRight)
|
||||
self.novelForm.setRowStretch(3, 1)
|
||||
# Grid Form
|
||||
self.addBox = QGridLayout()
|
||||
self.addBox.addWidget(QLabel(self.tr("Add a folder for plot notes")), 0, 0)
|
||||
self.addBox.addWidget(QLabel(self.tr("Add a folder for character notes")), 1, 0)
|
||||
self.addBox.addWidget(QLabel(self.tr("Add a folder for location notes")), 2, 0)
|
||||
self.addBox.addWidget(QLabel(self.tr("Add example notes to the above")), 3, 0)
|
||||
self.addBox.addWidget(QLabel(self.tr("Add chapters to the novel folder")), 4, 0)
|
||||
self.addBox.addWidget(QLabel(self.tr("Add scenes to each chapter")), 5, 0)
|
||||
self.addBox.addWidget(self.addPlot, 0, 1, 1, 1, Qt.AlignRight)
|
||||
self.addBox.addWidget(self.addChar, 1, 1, 1, 1, Qt.AlignRight)
|
||||
self.addBox.addWidget(self.addWorld, 2, 1, 1, 1, Qt.AlignRight)
|
||||
self.addBox.addWidget(self.addNotes, 3, 1, 1, 1, Qt.AlignRight)
|
||||
self.addBox.addWidget(self.numChapters, 4, 1, 1, 1, Qt.AlignRight)
|
||||
self.addBox.addWidget(self.numScenes, 5, 1, 1, 1, Qt.AlignRight)
|
||||
self.addBox.setVerticalSpacing(fS)
|
||||
self.addBox.setHorizontalSpacing(cM)
|
||||
self.addBox.setContentsMargins(cM, 0, cM, 0)
|
||||
self.addBox.setColumnStretch(2, 1)
|
||||
for i in range(6):
|
||||
self.addBox.setRowMinimumHeight(i, mH)
|
||||
|
||||
# Wizard Fields
|
||||
self.registerField("addPlot", self.addPlot)
|
||||
self.registerField("addChar", self.addChar)
|
||||
self.registerField("addWorld", self.addWorld)
|
||||
self.registerField("addTime", self.addTime)
|
||||
self.registerField("addObject", self.addObject)
|
||||
self.registerField("addEntity", self.addEntity)
|
||||
self.registerField("addNotes", self.addNotes)
|
||||
self.registerField("numChapters", self.numChapters)
|
||||
self.registerField("numScenes", self.numScenes)
|
||||
self.registerField("chFolders", self.chFolders)
|
||||
|
||||
# Assemble
|
||||
self.innerBox = QHBoxLayout()
|
||||
self.innerBox.addWidget(self.rootGroup)
|
||||
self.innerBox.addWidget(self.novelGroup)
|
||||
|
||||
self.outerBox = QVBoxLayout()
|
||||
self.outerBox.setSpacing(vS)
|
||||
self.outerBox.setSpacing(cM)
|
||||
self.outerBox.addWidget(self.theText)
|
||||
self.outerBox.addLayout(self.innerBox)
|
||||
self.outerBox.addLayout(self.addBox)
|
||||
self.outerBox.addStretch(1)
|
||||
self.setLayout(self.outerBox)
|
||||
|
||||
@@ -441,15 +402,8 @@ class ProjWizardFinalPage(QWizardPage):
|
||||
self.mainConf = novelwriter.CONFIG
|
||||
self.theWizard = theWizard
|
||||
|
||||
self.setTitle(self.tr("Finished"))
|
||||
self.theText = QLabel(
|
||||
"<p>%s</p><p>%s</p>" % (
|
||||
self.tr("All done."),
|
||||
self.tr("Press '{0}' to create the new project.").format(
|
||||
self.tr("Done") if self.mainConf.osDarwin else self.tr("Finish")
|
||||
)
|
||||
)
|
||||
)
|
||||
self.setTitle(self.tr("Summary"))
|
||||
self.theText = QLabel("")
|
||||
self.theText.setWordWrap(True)
|
||||
|
||||
# Assemble
|
||||
@@ -461,4 +415,51 @@ class ProjWizardFinalPage(QWizardPage):
|
||||
|
||||
return
|
||||
|
||||
def initializePage(self):
|
||||
"""Update the summary information on the final page.
|
||||
"""
|
||||
QWizardPage.initializePage(self)
|
||||
|
||||
sumList = []
|
||||
sumList.append(self.tr("Project Name: {0}").format(self.field("projName")))
|
||||
sumList.append(self.tr("Project Path: {0}").format(self.field("projPath")))
|
||||
|
||||
if self.field("popMinimal"):
|
||||
sumList.append(self.tr("Fill the project with a minimal set of items"))
|
||||
elif self.field("popSample"):
|
||||
sumList.append(self.tr("Fill the project with example files"))
|
||||
elif self.field("popCustom"):
|
||||
if self.field("addPlot"):
|
||||
sumList.append(self.tr("Add a folder for plot notes"))
|
||||
if self.field("addChar"):
|
||||
sumList.append(self.tr("Add a folder for character notes"))
|
||||
if self.field("addWorld"):
|
||||
sumList.append(self.tr("Add a folder for location notes"))
|
||||
if self.field("addNotes"):
|
||||
sumList.append(self.tr("Add example notes to the above"))
|
||||
if self.field("numChapters") > 0:
|
||||
sumList.append(self.tr("Add {0} chapters to the novel folder").format(
|
||||
self.field("numChapters")
|
||||
))
|
||||
if self.field("numScenes") > 0:
|
||||
sumList.append(self.tr("Add {0} scenes to each chapter").format(
|
||||
self.field("numScenes")
|
||||
))
|
||||
else:
|
||||
if self.field("numScenes") > 0:
|
||||
sumList.append(self.tr("Add {0} scenes").format(
|
||||
self.field("numScenes")
|
||||
))
|
||||
|
||||
self.theText.setText(
|
||||
"<p>%s</p><p> • %s</p><p>%s</p>" % (
|
||||
self.tr("You have selected the following:"),
|
||||
"<br> • ".join(sumList),
|
||||
self.tr("Press '{0}' to create the new project.").format(
|
||||
self.tr("Done") if self.mainConf.osDarwin else self.tr("Finish")
|
||||
)
|
||||
)
|
||||
)
|
||||
return
|
||||
|
||||
# END Class ProjWizardFinalPage
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<novelWriterXML appVersion="1.7-alpha0" hexVersion="0x010700a0" fileVersion="1.4" timeStamp="2022-04-23 15:34:25">
|
||||
<novelWriterXML appVersion="1.7-beta1" hexVersion="0x010700b1" fileVersion="1.4" timeStamp="2022-05-21 17:49:23">
|
||||
<project>
|
||||
<name>Test Custom</name>
|
||||
<title>Test Novel</title>
|
||||
@@ -29,110 +29,106 @@
|
||||
<section></section>
|
||||
</titleFormat>
|
||||
<status>
|
||||
<entry key="s000008" count="17" red="100" green="100" blue="100">New</entry>
|
||||
<entry key="s000008" count="15" red="100" green="100" blue="100">New</entry>
|
||||
<entry key="s000009" count="0" red="200" green="50" blue="0">Note</entry>
|
||||
<entry key="s00000a" count="0" red="200" green="150" blue="0">Draft</entry>
|
||||
<entry key="s00000b" count="0" red="50" green="200" blue="0">Finished</entry>
|
||||
</status>
|
||||
<importance>
|
||||
<entry key="i00000c" count="6" red="100" green="100" blue="100">New</entry>
|
||||
<entry key="i00000c" count="7" red="100" green="100" blue="100">New</entry>
|
||||
<entry key="i00000d" count="0" red="200" green="50" blue="0">Minor</entry>
|
||||
<entry key="i00000e" count="0" red="200" green="150" blue="0">Major</entry>
|
||||
<entry key="i00000f" count="0" red="50" green="200" blue="0">Main</entry>
|
||||
</importance>
|
||||
</settings>
|
||||
<content count="23">
|
||||
<content count="22">
|
||||
<item handle="0000000000010" parent="None" root="0000000000010" order="0" type="ROOT" class="NOVEL">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Novel</name>
|
||||
</item>
|
||||
<item handle="0000000000011" parent="None" root="0000000000011" order="0" type="ROOT" class="PLOT">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Plot</name>
|
||||
</item>
|
||||
<item handle="0000000000012" parent="None" root="0000000000012" order="0" type="ROOT" class="CHARACTER">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Characters</name>
|
||||
</item>
|
||||
<item handle="0000000000013" parent="None" root="0000000000013" order="0" type="ROOT" class="WORLD">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Locations</name>
|
||||
</item>
|
||||
<item handle="0000000000014" parent="None" root="0000000000014" order="0" type="ROOT" class="TIMELINE">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Timeline</name>
|
||||
</item>
|
||||
<item handle="0000000000015" parent="None" root="0000000000015" order="0" type="ROOT" class="OBJECT">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Objects</name>
|
||||
</item>
|
||||
<item handle="0000000000016" parent="None" root="0000000000016" order="0" type="ROOT" class="ENTITY">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Entities</name>
|
||||
</item>
|
||||
<item handle="0000000000017" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="0000000000011" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Title Page</name>
|
||||
</item>
|
||||
<item handle="0000000000018" parent="0000000000010" root="0000000000010" order="0" type="FOLDER" class="NOVEL">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Chapter 1</name>
|
||||
</item>
|
||||
<item handle="0000000000019" parent="0000000000018" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="0000000000012" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Chapter 1</name>
|
||||
</item>
|
||||
<item handle="000000000001a" parent="0000000000018" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="0000000000013" parent="0000000000012" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Scene 1.1</name>
|
||||
</item>
|
||||
<item handle="000000000001b" parent="0000000000018" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="0000000000014" parent="0000000000012" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Scene 1.2</name>
|
||||
</item>
|
||||
<item handle="000000000001c" parent="0000000000018" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="0000000000015" parent="0000000000012" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Scene 1.3</name>
|
||||
</item>
|
||||
<item handle="000000000001d" parent="0000000000010" root="0000000000010" order="0" type="FOLDER" class="NOVEL">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Chapter 2</name>
|
||||
</item>
|
||||
<item handle="000000000001e" parent="000000000001d" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="0000000000016" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Chapter 2</name>
|
||||
</item>
|
||||
<item handle="000000000001f" parent="000000000001d" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="0000000000017" parent="0000000000016" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Scene 2.1</name>
|
||||
</item>
|
||||
<item handle="0000000000020" parent="000000000001d" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="0000000000018" parent="0000000000016" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Scene 2.2</name>
|
||||
</item>
|
||||
<item handle="0000000000021" parent="000000000001d" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="0000000000019" parent="0000000000016" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Scene 2.3</name>
|
||||
</item>
|
||||
<item handle="0000000000022" parent="0000000000010" root="0000000000010" order="0" type="FOLDER" class="NOVEL">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Chapter 3</name>
|
||||
</item>
|
||||
<item handle="0000000000023" parent="0000000000022" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="000000000001a" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Chapter 3</name>
|
||||
</item>
|
||||
<item handle="0000000000024" parent="0000000000022" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="000000000001b" parent="000000000001a" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Scene 3.1</name>
|
||||
</item>
|
||||
<item handle="0000000000025" parent="0000000000022" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="000000000001c" parent="000000000001a" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Scene 3.2</name>
|
||||
</item>
|
||||
<item handle="0000000000026" parent="0000000000022" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="000000000001d" parent="000000000001a" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Scene 3.3</name>
|
||||
</item>
|
||||
<item handle="000000000001e" parent="None" root="000000000001e" order="0" type="ROOT" class="PLOT">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Plot</name>
|
||||
</item>
|
||||
<item handle="000000000001f" parent="000000000001e" root="000000000001e" order="0" type="FILE" class="PLOT" layout="NOTE">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Main Plot</name>
|
||||
</item>
|
||||
<item handle="0000000000020" parent="None" root="0000000000020" order="0" type="ROOT" class="CHARACTER">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Characters</name>
|
||||
</item>
|
||||
<item handle="0000000000021" parent="0000000000020" root="0000000000020" order="0" type="FILE" class="CHARACTER" layout="NOTE">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Protagonist</name>
|
||||
</item>
|
||||
<item handle="0000000000022" parent="None" root="0000000000022" order="0" type="ROOT" class="WORLD">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Locations</name>
|
||||
</item>
|
||||
<item handle="0000000000023" parent="0000000000022" root="0000000000022" order="0" type="FILE" class="WORLD" layout="NOTE">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Main Location</name>
|
||||
</item>
|
||||
<item handle="0000000000024" parent="None" root="0000000000024" order="0" type="ROOT" class="ARCHIVE">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Archive</name>
|
||||
</item>
|
||||
<item handle="0000000000025" parent="None" root="0000000000025" order="0" type="ROOT" class="TRASH">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Trash</name>
|
||||
</item>
|
||||
</content>
|
||||
</novelWriterXML>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<novelWriterXML appVersion="1.7-alpha0" hexVersion="0x010700a0" fileVersion="1.4" timeStamp="2022-04-23 15:34:25">
|
||||
<novelWriterXML appVersion="1.7-beta1" hexVersion="0x010700b1" fileVersion="1.4" timeStamp="2022-05-21 17:48:40">
|
||||
<project>
|
||||
<name>Test Custom</name>
|
||||
<title>Test Novel</title>
|
||||
@@ -29,74 +29,82 @@
|
||||
<section></section>
|
||||
</titleFormat>
|
||||
<status>
|
||||
<entry key="s000008" count="8" red="100" green="100" blue="100">New</entry>
|
||||
<entry key="s000008" count="9" red="100" green="100" blue="100">New</entry>
|
||||
<entry key="s000009" count="0" red="200" green="50" blue="0">Note</entry>
|
||||
<entry key="s00000a" count="0" red="200" green="150" blue="0">Draft</entry>
|
||||
<entry key="s00000b" count="0" red="50" green="200" blue="0">Finished</entry>
|
||||
</status>
|
||||
<importance>
|
||||
<entry key="i00000c" count="6" red="100" green="100" blue="100">New</entry>
|
||||
<entry key="i00000c" count="7" red="100" green="100" blue="100">New</entry>
|
||||
<entry key="i00000d" count="0" red="200" green="50" blue="0">Minor</entry>
|
||||
<entry key="i00000e" count="0" red="200" green="150" blue="0">Major</entry>
|
||||
<entry key="i00000f" count="0" red="50" green="200" blue="0">Main</entry>
|
||||
</importance>
|
||||
</settings>
|
||||
<content count="14">
|
||||
<content count="16">
|
||||
<item handle="0000000000010" parent="None" root="0000000000010" order="0" type="ROOT" class="NOVEL">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Novel</name>
|
||||
</item>
|
||||
<item handle="0000000000011" parent="None" root="0000000000011" order="0" type="ROOT" class="PLOT">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Plot</name>
|
||||
</item>
|
||||
<item handle="0000000000012" parent="None" root="0000000000012" order="0" type="ROOT" class="CHARACTER">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Characters</name>
|
||||
</item>
|
||||
<item handle="0000000000013" parent="None" root="0000000000013" order="0" type="ROOT" class="WORLD">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Locations</name>
|
||||
</item>
|
||||
<item handle="0000000000014" parent="None" root="0000000000014" order="0" type="ROOT" class="TIMELINE">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Timeline</name>
|
||||
</item>
|
||||
<item handle="0000000000015" parent="None" root="0000000000015" order="0" type="ROOT" class="OBJECT">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Objects</name>
|
||||
</item>
|
||||
<item handle="0000000000016" parent="None" root="0000000000016" order="0" type="ROOT" class="ENTITY">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Entities</name>
|
||||
</item>
|
||||
<item handle="0000000000017" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="0000000000011" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Title Page</name>
|
||||
</item>
|
||||
<item handle="0000000000018" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="0000000000012" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Scene 1</name>
|
||||
</item>
|
||||
<item handle="0000000000019" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="0000000000013" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Scene 2</name>
|
||||
</item>
|
||||
<item handle="000000000001a" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="0000000000014" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Scene 3</name>
|
||||
</item>
|
||||
<item handle="000000000001b" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="0000000000015" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Scene 4</name>
|
||||
</item>
|
||||
<item handle="000000000001c" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="0000000000016" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Scene 5</name>
|
||||
</item>
|
||||
<item handle="000000000001d" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="0000000000017" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Scene 6</name>
|
||||
</item>
|
||||
<item handle="0000000000018" parent="None" root="0000000000018" order="0" type="ROOT" class="PLOT">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Plot</name>
|
||||
</item>
|
||||
<item handle="0000000000019" parent="0000000000018" root="0000000000018" order="0" type="FILE" class="PLOT" layout="NOTE">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Main Plot</name>
|
||||
</item>
|
||||
<item handle="000000000001a" parent="None" root="000000000001a" order="0" type="ROOT" class="CHARACTER">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Characters</name>
|
||||
</item>
|
||||
<item handle="000000000001b" parent="000000000001a" root="000000000001a" order="0" type="FILE" class="CHARACTER" layout="NOTE">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Protagonist</name>
|
||||
</item>
|
||||
<item handle="000000000001c" parent="None" root="000000000001c" order="0" type="ROOT" class="WORLD">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Locations</name>
|
||||
</item>
|
||||
<item handle="000000000001d" parent="000000000001c" root="000000000001c" order="0" type="FILE" class="WORLD" layout="NOTE">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Main Location</name>
|
||||
</item>
|
||||
<item handle="000000000001e" parent="None" root="000000000001e" order="0" type="ROOT" class="ARCHIVE">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Archive</name>
|
||||
</item>
|
||||
<item handle="000000000001f" parent="None" root="000000000001f" order="0" type="ROOT" class="TRASH">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Trash</name>
|
||||
</item>
|
||||
</content>
|
||||
</novelWriterXML>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<novelWriterXML appVersion="1.7-alpha0" hexVersion="0x010700a0" fileVersion="1.4" timeStamp="2022-04-23 15:34:25">
|
||||
<novelWriterXML appVersion="1.7-beta1" hexVersion="0x010700b1" fileVersion="1.4" timeStamp="2022-05-21 17:08:21">
|
||||
<project>
|
||||
<name>New Project</name>
|
||||
<title></title>
|
||||
<title>New Novel</title>
|
||||
<author>Jane Doe</author>
|
||||
<saveCount>2</saveCount>
|
||||
<autoCount>1</autoCount>
|
||||
<editTime>0</editTime>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<novelWriterXML appVersion="1.7-alpha0" hexVersion="0x010700a0" fileVersion="1.4" timeStamp="2022-04-23 15:34:25">
|
||||
<novelWriterXML appVersion="1.7-beta1" hexVersion="0x010700b1" fileVersion="1.4" timeStamp="2022-05-21 17:50:26">
|
||||
<project>
|
||||
<name>New Project</name>
|
||||
<title></title>
|
||||
@@ -44,33 +44,33 @@
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Novel</name>
|
||||
</item>
|
||||
<item handle="0000000000011" parent="None" root="0000000000011" order="0" type="ROOT" class="PLOT">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Plot</name>
|
||||
</item>
|
||||
<item handle="0000000000012" parent="None" root="0000000000012" order="0" type="ROOT" class="CHARACTER">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Characters</name>
|
||||
</item>
|
||||
<item handle="0000000000013" parent="None" root="0000000000013" order="0" type="ROOT" class="WORLD">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">World</name>
|
||||
</item>
|
||||
<item handle="0000000000014" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="0000000000011" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">Title Page</name>
|
||||
</item>
|
||||
<item handle="0000000000015" parent="0000000000010" root="0000000000010" order="0" type="FOLDER" class="NOVEL">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">New Chapter</name>
|
||||
</item>
|
||||
<item handle="0000000000016" parent="0000000000015" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="0000000000012" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">New Chapter</name>
|
||||
</item>
|
||||
<item handle="0000000000017" parent="0000000000015" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<item handle="0000000000013" parent="0000000000012" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
|
||||
<name status="s000008" import="i00000c" exported="True">New Scene</name>
|
||||
</item>
|
||||
<item handle="0000000000014" parent="None" root="0000000000014" order="0" type="ROOT" class="PLOT">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Plot</name>
|
||||
</item>
|
||||
<item handle="0000000000015" parent="None" root="0000000000015" order="0" type="ROOT" class="CHARACTER">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Characters</name>
|
||||
</item>
|
||||
<item handle="0000000000016" parent="None" root="0000000000016" order="0" type="ROOT" class="WORLD">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Locations</name>
|
||||
</item>
|
||||
<item handle="0000000000017" parent="None" root="0000000000017" order="0" type="ROOT" class="ARCHIVE">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Archive</name>
|
||||
</item>
|
||||
</content>
|
||||
</novelWriterXML>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<novelWriterXML appVersion="1.7-alpha0" hexVersion="0x010700a0" fileVersion="1.4" timeStamp="2022-04-23 15:34:25">
|
||||
<novelWriterXML appVersion="1.7-beta1" hexVersion="0x010700b1" fileVersion="1.4" timeStamp="2022-05-21 22:07:28">
|
||||
<project>
|
||||
<name>New Project</name>
|
||||
<title></title>
|
||||
<title>New Novel</title>
|
||||
<author>Jane Doe</author>
|
||||
<saveCount>2</saveCount>
|
||||
<autoCount>1</autoCount>
|
||||
<editTime>0</editTime>
|
||||
@@ -82,11 +83,11 @@
|
||||
</item>
|
||||
<item handle="000000000002a" parent="None" root="000000000002a" order="0" type="ROOT" class="CHARACTER">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Character</name>
|
||||
<name status="s000008" import="i00000c">Characters</name>
|
||||
</item>
|
||||
<item handle="000000000002b" parent="None" root="000000000002b" order="0" type="ROOT" class="WORLD">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">World</name>
|
||||
<name status="s000008" import="i00000c">Locations</name>
|
||||
</item>
|
||||
<item handle="000000000002c" parent="None" root="000000000002c" order="0" type="ROOT" class="TIMELINE">
|
||||
<meta expanded="False"/>
|
||||
@@ -94,15 +95,15 @@
|
||||
</item>
|
||||
<item handle="000000000002d" parent="None" root="000000000002d" order="0" type="ROOT" class="OBJECT">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Object</name>
|
||||
<name status="s000008" import="i00000c">Objects</name>
|
||||
</item>
|
||||
<item handle="000000000002e" parent="None" root="000000000002e" order="0" type="ROOT" class="CUSTOM">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Custom1</name>
|
||||
<name status="s000008" import="i00000c">Custom</name>
|
||||
</item>
|
||||
<item handle="000000000002f" parent="None" root="000000000002f" order="0" type="ROOT" class="CUSTOM">
|
||||
<meta expanded="False"/>
|
||||
<name status="s000008" import="i00000c">Custom2</name>
|
||||
<name status="s000008" import="i00000c">Custom</name>
|
||||
</item>
|
||||
</content>
|
||||
</novelWriterXML>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<novelWriterXML appVersion="1.7-alpha0" hexVersion="0x010700a0" fileVersion="1.4" timeStamp="2022-04-23 16:55:50">
|
||||
<novelWriterXML appVersion="1.7-beta1" hexVersion="0x010700b1" fileVersion="1.4" timeStamp="2022-05-21 17:27:16">
|
||||
<project>
|
||||
<name>New Project</name>
|
||||
<title></title>
|
||||
<saveCount>5</saveCount>
|
||||
<title>New Novel</title>
|
||||
<author>Jane Doe</author>
|
||||
<saveCount>4</saveCount>
|
||||
<autoCount>2</autoCount>
|
||||
<editTime>3</editTime>
|
||||
</project>
|
||||
@@ -15,8 +16,8 @@
|
||||
<autoOutline>True</autoOutline>
|
||||
<lastEdited>000000000000f</lastEdited>
|
||||
<lastViewed>None</lastViewed>
|
||||
<lastWordCount>126</lastWordCount>
|
||||
<novelWordCount>99</novelWordCount>
|
||||
<lastWordCount>129</lastWordCount>
|
||||
<novelWordCount>102</novelWordCount>
|
||||
<notesWordCount>27</notesWordCount>
|
||||
<autoReplace/>
|
||||
<titleFormat>
|
||||
@@ -45,7 +46,7 @@
|
||||
<name status="s000000" import="i000004">Novel</name>
|
||||
</item>
|
||||
<item handle="000000000000c" parent="0000000000008" root="0000000000008" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="11" wordCount="2" paraCount="0" cursorPos="0"/>
|
||||
<meta expanded="False" charCount="20" wordCount="5" paraCount="1" cursorPos="0"/>
|
||||
<name status="s000000" import="i000004" exported="True">Title Page</name>
|
||||
</item>
|
||||
<item handle="000000000000d" parent="0000000000008" root="0000000000008" order="1" type="FOLDER" class="NOVEL">
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<novelWriterXML appVersion="1.7-alpha0" hexVersion="0x010700a0" fileVersion="1.4" timeStamp="2022-04-23 15:28:44">
|
||||
<novelWriterXML appVersion="1.7-beta1" hexVersion="0x010700b1" fileVersion="1.4" timeStamp="2022-05-21 17:25:41">
|
||||
<project>
|
||||
<name>New Project</name>
|
||||
<title></title>
|
||||
<saveCount>3</saveCount>
|
||||
<title>New Novel</title>
|
||||
<author>Jane Doe</author>
|
||||
<saveCount>2</saveCount>
|
||||
<autoCount>1</autoCount>
|
||||
<editTime>0</editTime>
|
||||
</project>
|
||||
@@ -15,8 +16,8 @@
|
||||
<autoOutline>True</autoOutline>
|
||||
<lastEdited>None</lastEdited>
|
||||
<lastViewed>None</lastViewed>
|
||||
<lastWordCount>6</lastWordCount>
|
||||
<novelWordCount>6</novelWordCount>
|
||||
<lastWordCount>9</lastWordCount>
|
||||
<novelWordCount>9</novelWordCount>
|
||||
<notesWordCount>0</notesWordCount>
|
||||
<autoReplace/>
|
||||
<titleFormat>
|
||||
@@ -45,7 +46,7 @@
|
||||
<name status="s000000" import="i000004">Novel</name>
|
||||
</item>
|
||||
<item handle="000000000000c" parent="0000000000008" root="0000000000008" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="11" wordCount="2" paraCount="0" cursorPos="0"/>
|
||||
<meta expanded="False" charCount="20" wordCount="5" paraCount="1" cursorPos="0"/>
|
||||
<name status="s000000" import="i000004" exported="True">Title Page</name>
|
||||
</item>
|
||||
<item handle="000000000000d" parent="0000000000008" root="0000000000008" order="1" type="FOLDER" class="NOVEL">
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<novelWriterXML appVersion="1.7-alpha0" hexVersion="0x010700a0" fileVersion="1.4" timeStamp="2022-04-23 15:28:41">
|
||||
<novelWriterXML appVersion="1.7-beta1" hexVersion="0x010700b1" fileVersion="1.4" timeStamp="2022-05-21 17:31:17">
|
||||
<project>
|
||||
<name>Project Name</name>
|
||||
<title>Project Title</title>
|
||||
<author>Jane Doe</author>
|
||||
<author>John Doh</author>
|
||||
<saveCount>2</saveCount>
|
||||
<saveCount>1</saveCount>
|
||||
<autoCount>1</autoCount>
|
||||
<editTime>0</editTime>
|
||||
</project>
|
||||
@@ -17,8 +17,8 @@
|
||||
<autoOutline>True</autoOutline>
|
||||
<lastEdited>None</lastEdited>
|
||||
<lastViewed>None</lastViewed>
|
||||
<lastWordCount>6</lastWordCount>
|
||||
<novelWordCount>6</novelWordCount>
|
||||
<lastWordCount>9</lastWordCount>
|
||||
<novelWordCount>9</novelWordCount>
|
||||
<notesWordCount>0</notesWordCount>
|
||||
<autoReplace>
|
||||
<entry key="A">B</entry>
|
||||
@@ -51,7 +51,7 @@
|
||||
<name status="s000000" import="i000004">Novel</name>
|
||||
</item>
|
||||
<item handle="000000000000c" parent="0000000000008" root="0000000000008" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||
<meta expanded="False" charCount="11" wordCount="2" paraCount="0" cursorPos="0"/>
|
||||
<meta expanded="False" charCount="20" wordCount="5" paraCount="1" cursorPos="0"/>
|
||||
<name status="s000000" import="i000004" exported="True">Title Page</name>
|
||||
</item>
|
||||
<item handle="000000000000d" parent="0000000000008" root="0000000000008" order="1" type="FOLDER" class="NOVEL">
|
||||
|
||||
@@ -280,7 +280,7 @@ def testCoreIndex_ScanText(nwMinimal, mockGUI):
|
||||
assert theIndex.scanText(xHandle, "Hello World!") is False
|
||||
|
||||
# Create the archive root
|
||||
aHandle = theProject.newRoot("Archive", nwItemClass.ARCHIVE)
|
||||
aHandle = theProject.newRoot(nwItemClass.ARCHIVE)
|
||||
assert theProject.projTree[aHandle] is not None
|
||||
xItem.setParent(aHandle)
|
||||
theProject.projTree.updateItemData(xItem.itemHandle)
|
||||
|
||||
@@ -26,7 +26,7 @@ from shutil import copyfile
|
||||
from zipfile import ZipFile
|
||||
from lxml import etree
|
||||
|
||||
from tools import cmpFiles, writeFile, readFile
|
||||
from tools import cmpFiles, writeFile, readFile, buildTestProject, XML_IGNORE
|
||||
from mock import causeOSError
|
||||
|
||||
from novelwriter.core.project import NWProject
|
||||
@@ -67,7 +67,7 @@ def testCoreProject_NewMinimal(fncDir, outDir, refDir, mockGUI, mockRnd):
|
||||
assert theProject.saveProject() is True
|
||||
assert theProject.closeProject() is True
|
||||
copyfile(projFile, testFile)
|
||||
assert cmpFiles(testFile, compFile, [2, 6, 7, 8])
|
||||
assert cmpFiles(testFile, compFile, ignoreStart=XML_IGNORE)
|
||||
assert theProject.projChanged is False
|
||||
|
||||
# Open a second time
|
||||
@@ -77,7 +77,7 @@ def testCoreProject_NewMinimal(fncDir, outDir, refDir, mockGUI, mockRnd):
|
||||
assert theProject.saveProject() is True
|
||||
assert theProject.closeProject() is True
|
||||
copyfile(projFile, testFile)
|
||||
assert cmpFiles(testFile, compFile, [2, 6, 7, 8])
|
||||
assert cmpFiles(testFile, compFile, ignoreStart=XML_IGNORE)
|
||||
|
||||
# END Test testCoreProject_NewMinimal
|
||||
|
||||
@@ -103,13 +103,10 @@ def testCoreProject_NewCustomA(fncDir, outDir, refDir, mockGUI, mockRnd):
|
||||
nwItemClass.PLOT,
|
||||
nwItemClass.CHARACTER,
|
||||
nwItemClass.WORLD,
|
||||
nwItemClass.TIMELINE,
|
||||
nwItemClass.OBJECT,
|
||||
nwItemClass.ENTITY,
|
||||
],
|
||||
"addNotes": True,
|
||||
"numChapters": 3,
|
||||
"numScenes": 3,
|
||||
"chFolders": True,
|
||||
}
|
||||
theProject = NWProject(mockGUI)
|
||||
|
||||
@@ -118,7 +115,7 @@ def testCoreProject_NewCustomA(fncDir, outDir, refDir, mockGUI, mockRnd):
|
||||
assert theProject.closeProject() is True
|
||||
|
||||
copyfile(projFile, testFile)
|
||||
assert cmpFiles(testFile, compFile, [2, 6, 7, 8])
|
||||
assert cmpFiles(testFile, compFile, ignoreStart=XML_IGNORE)
|
||||
|
||||
# END Test testCoreProject_NewCustomA
|
||||
|
||||
@@ -144,13 +141,10 @@ def testCoreProject_NewCustomB(fncDir, outDir, refDir, mockGUI, mockRnd):
|
||||
nwItemClass.PLOT,
|
||||
nwItemClass.CHARACTER,
|
||||
nwItemClass.WORLD,
|
||||
nwItemClass.TIMELINE,
|
||||
nwItemClass.OBJECT,
|
||||
nwItemClass.ENTITY,
|
||||
],
|
||||
"addNotes": True,
|
||||
"numChapters": 0,
|
||||
"numScenes": 6,
|
||||
"chFolders": True,
|
||||
}
|
||||
theProject = NWProject(mockGUI)
|
||||
|
||||
@@ -159,7 +153,7 @@ def testCoreProject_NewCustomB(fncDir, outDir, refDir, mockGUI, mockRnd):
|
||||
assert theProject.closeProject() is True
|
||||
|
||||
copyfile(projFile, testFile)
|
||||
assert cmpFiles(testFile, compFile, [2, 6, 7, 8])
|
||||
assert cmpFiles(testFile, compFile, ignoreStart=XML_IGNORE)
|
||||
|
||||
# END Test testCoreProject_NewCustomB
|
||||
|
||||
@@ -258,28 +252,28 @@ def testCoreProject_NewRoot(fncDir, outDir, refDir, mockGUI, mockRnd):
|
||||
compFile = os.path.join(refDir, "coreProject_NewRoot_nwProject.nwx")
|
||||
|
||||
theProject = NWProject(mockGUI)
|
||||
buildTestProject(theProject, fncDir)
|
||||
|
||||
assert theProject.newProject({"projPath": fncDir}) is True
|
||||
assert theProject.setProjectPath(fncDir) is True
|
||||
assert theProject.saveProject() is True
|
||||
assert theProject.closeProject() is True
|
||||
assert theProject.openProject(projFile) is True
|
||||
|
||||
assert isinstance(theProject.newRoot("Novel", nwItemClass.NOVEL), str)
|
||||
assert isinstance(theProject.newRoot("Plot", nwItemClass.PLOT), str)
|
||||
assert isinstance(theProject.newRoot("Character", nwItemClass.CHARACTER), str)
|
||||
assert isinstance(theProject.newRoot("World", nwItemClass.WORLD), str)
|
||||
assert isinstance(theProject.newRoot("Timeline", nwItemClass.TIMELINE), str)
|
||||
assert isinstance(theProject.newRoot("Object", nwItemClass.OBJECT), str)
|
||||
assert isinstance(theProject.newRoot("Custom1", nwItemClass.CUSTOM), str)
|
||||
assert isinstance(theProject.newRoot("Custom2", nwItemClass.CUSTOM), str)
|
||||
assert isinstance(theProject.newRoot(nwItemClass.NOVEL), str)
|
||||
assert isinstance(theProject.newRoot(nwItemClass.PLOT), str)
|
||||
assert isinstance(theProject.newRoot(nwItemClass.CHARACTER), str)
|
||||
assert isinstance(theProject.newRoot(nwItemClass.WORLD), str)
|
||||
assert isinstance(theProject.newRoot(nwItemClass.TIMELINE), str)
|
||||
assert isinstance(theProject.newRoot(nwItemClass.OBJECT), str)
|
||||
assert isinstance(theProject.newRoot(nwItemClass.CUSTOM), str)
|
||||
assert isinstance(theProject.newRoot(nwItemClass.CUSTOM), str)
|
||||
|
||||
assert theProject.projChanged is True
|
||||
assert theProject.saveProject() is True
|
||||
assert theProject.closeProject() is True
|
||||
|
||||
copyfile(projFile, testFile)
|
||||
assert cmpFiles(testFile, compFile, [2, 6, 7, 8])
|
||||
assert cmpFiles(testFile, compFile, ignoreStart=XML_IGNORE)
|
||||
assert theProject.projChanged is False
|
||||
|
||||
# END Test testCoreProject_NewRoot
|
||||
@@ -294,8 +288,8 @@ def testCoreProject_NewFile(fncDir, outDir, refDir, mockGUI, mockRnd):
|
||||
compFile = os.path.join(refDir, "coreProject_NewFile_nwProject.nwx")
|
||||
|
||||
theProject = NWProject(mockGUI)
|
||||
buildTestProject(theProject, fncDir)
|
||||
|
||||
assert theProject.newProject({"projPath": fncDir}) is True
|
||||
assert theProject.setProjectPath(fncDir) is True
|
||||
assert theProject.saveProject() is True
|
||||
assert theProject.closeProject() is True
|
||||
@@ -308,7 +302,7 @@ def testCoreProject_NewFile(fncDir, outDir, refDir, mockGUI, mockRnd):
|
||||
assert theProject.closeProject() is True
|
||||
|
||||
copyfile(projFile, testFile)
|
||||
assert cmpFiles(testFile, compFile, [2, 6, 7, 8])
|
||||
assert cmpFiles(testFile, compFile, ignoreStart=XML_IGNORE)
|
||||
assert theProject.projChanged is False
|
||||
|
||||
# END Test testCoreProject_NewFile
|
||||
@@ -489,7 +483,7 @@ def testCoreProject_Save(monkeypatch, nwMinimal, mockGUI, refDir):
|
||||
assert theProject.saveProject() is True
|
||||
assert theProject.saveCount == saveCount + 1
|
||||
assert theProject.autoCount == autoCount
|
||||
assert cmpFiles(testFile, compFile, [2, 6, 7, 8, 9])
|
||||
assert cmpFiles(testFile, compFile, ignoreStart=XML_IGNORE)
|
||||
|
||||
# Check that a second save creates a .bak file
|
||||
assert os.path.isfile(backFile) is True
|
||||
@@ -500,7 +494,7 @@ def testCoreProject_Save(monkeypatch, nwMinimal, mockGUI, refDir):
|
||||
assert theProject.saveProject(autoSave=True) is True
|
||||
assert theProject.saveCount == saveCount
|
||||
assert theProject.autoCount == autoCount + 1
|
||||
assert cmpFiles(testFile, compFile, [2, 6, 7, 8, 9])
|
||||
assert cmpFiles(testFile, compFile, ignoreStart=XML_IGNORE)
|
||||
|
||||
# Close test project
|
||||
assert theProject.closeProject()
|
||||
@@ -677,7 +671,7 @@ def testCoreProject_StatusImport(mockGUI, fncDir, mockRnd):
|
||||
"""Test the status and importance flag handling.
|
||||
"""
|
||||
theProject = NWProject(mockGUI)
|
||||
assert theProject.newProject({"projPath": fncDir}) is True
|
||||
buildTestProject(theProject, fncDir)
|
||||
|
||||
statusKeys = ["s000008", "s000009", "s00000a", "s00000b"]
|
||||
importKeys = ["i00000c", "i00000d", "i00000e", "i00000f"]
|
||||
@@ -798,7 +792,7 @@ def testCoreProject_Methods(monkeypatch, mockGUI, tmpDir, fncDir, mockRnd):
|
||||
"""Test other project class methods and functions.
|
||||
"""
|
||||
theProject = NWProject(mockGUI)
|
||||
assert theProject.newProject({"projPath": fncDir}) is True
|
||||
buildTestProject(theProject, fncDir)
|
||||
|
||||
# Setting project path
|
||||
assert theProject.setProjectPath(None)
|
||||
@@ -1178,10 +1172,6 @@ def testCoreProject_LegacyData(monkeypatch, mockGUI, fncDir):
|
||||
theProject = NWProject(mockGUI)
|
||||
theProject.setProjectPath(fncDir)
|
||||
|
||||
# assert theProject.newProject({"projPath": fncDir})
|
||||
# assert theProject.saveProject()
|
||||
# assert theProject.closeProject()
|
||||
|
||||
# Check behaviour of deprecated files function on OSError
|
||||
tstFile = os.path.join(fncDir, "ToC.json")
|
||||
writeFile(tstFile, "stuff")
|
||||
|
||||
@@ -23,7 +23,7 @@ import os
|
||||
import pytest
|
||||
|
||||
from mock import causeOSError
|
||||
from tools import getGuiItem, readFile, writeFile
|
||||
from tools import getGuiItem, readFile, writeFile, buildTestProject
|
||||
|
||||
from PyQt5.QtWidgets import QAction, QMessageBox, QDialog
|
||||
|
||||
@@ -41,7 +41,7 @@ def testDlgMerge_Main(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
|
||||
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Ok)
|
||||
|
||||
# Create a new project
|
||||
assert nwGUI.newProject({"projPath": fncProj})
|
||||
buildTestProject(nwGUI, fncProj)
|
||||
|
||||
# Handles for new objects
|
||||
hNovelRoot = "0000000000008"
|
||||
|
||||
@@ -23,7 +23,7 @@ import os
|
||||
import pytest
|
||||
|
||||
from mock import causeOSError
|
||||
from tools import getGuiItem, readFile, writeFile
|
||||
from tools import getGuiItem, readFile, writeFile, buildTestProject
|
||||
|
||||
from PyQt5.QtWidgets import QAction, QMessageBox, QDialog
|
||||
|
||||
@@ -42,7 +42,7 @@ def testDlgSplit_Main(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
|
||||
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Ok)
|
||||
|
||||
# Create a new project
|
||||
assert nwGUI.newProject({"projPath": fncProj}) is True
|
||||
buildTestProject(nwGUI, fncProj)
|
||||
|
||||
# Handles for new objects
|
||||
hNovelRoot = "0000000000008"
|
||||
|
||||
@@ -21,7 +21,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
from tools import getGuiItem
|
||||
from tools import getGuiItem, buildTestProject
|
||||
|
||||
from PyQt5.QtWidgets import QAction, QDialog, QMessageBox
|
||||
|
||||
@@ -48,7 +48,7 @@ def testDlgItemEditor_Dialog(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
|
||||
assert nwGUI.editItem() is False
|
||||
|
||||
# Create and Open Project
|
||||
assert nwGUI.newProject({"projPath": fncProj})
|
||||
buildTestProject(nwGUI, fncProj)
|
||||
tHandle = "000000000000f"
|
||||
|
||||
# No Selection
|
||||
@@ -99,7 +99,7 @@ def testDlgItemEditor_Novel(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
|
||||
monkeypatch.setattr(GuiProjectTree, "hasFocus", lambda *a: True)
|
||||
|
||||
# Create Project and Open Document
|
||||
assert nwGUI.newProject({"projPath": fncProj})
|
||||
buildTestProject(nwGUI, fncProj)
|
||||
tHandle = "000000000000f"
|
||||
|
||||
assert nwGUI.theProject.statusItems.name(statusKeys[0]) == "New"
|
||||
@@ -156,7 +156,7 @@ def testDlgItemEditor_Note(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
|
||||
monkeypatch.setattr(GuiProjectTree, "hasFocus", lambda *a: True)
|
||||
|
||||
# Create Project and Open Document
|
||||
assert nwGUI.newProject({"projPath": fncProj})
|
||||
buildTestProject(nwGUI, fncProj)
|
||||
assert nwGUI.theProject.statusItems.name(statusKeys[0]) == "New"
|
||||
assert nwGUI.theProject.statusItems.name(statusKeys[1]) == "Note"
|
||||
assert nwGUI.theProject.importItems.name(importKeys[0]) == "New"
|
||||
@@ -209,7 +209,7 @@ def testDlgItemEditor_Folder(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
|
||||
monkeypatch.setattr(GuiProjectTree, "hasFocus", lambda *a: True)
|
||||
|
||||
# Create Project and Open Document
|
||||
assert nwGUI.newProject({"projPath": fncProj})
|
||||
buildTestProject(nwGUI, fncProj)
|
||||
|
||||
# Edit a Folder
|
||||
itemEdit = GuiItemEditor(nwGUI, "000000000000d")
|
||||
|
||||
@@ -23,7 +23,7 @@ import os
|
||||
import pytest
|
||||
|
||||
from shutil import copyfile
|
||||
from tools import cmpFiles, getGuiItem
|
||||
from tools import cmpFiles, getGuiItem, buildTestProject
|
||||
|
||||
from PyQt5.QtGui import QColor
|
||||
from PyQt5.QtCore import Qt
|
||||
@@ -57,7 +57,7 @@ def testDlgProjSettings_Dialog(
|
||||
assert getGuiItem("GuiProjectSettings") is None
|
||||
|
||||
# Create new project
|
||||
assert nwGUI.newProject({"projPath": fncProj})
|
||||
buildTestProject(nwGUI, fncProj)
|
||||
nwGUI.mainConf.backupPath = fncDir
|
||||
|
||||
nwGUI.theProject.setSpellLang("en")
|
||||
@@ -81,7 +81,7 @@ def testDlgProjSettings_Dialog(
|
||||
# ============
|
||||
|
||||
assert projEdit.tabMain.editName.text() == "New Project"
|
||||
assert projEdit.tabMain.editTitle.text() == ""
|
||||
assert projEdit.tabMain.editTitle.text() == "New Novel"
|
||||
assert projEdit.tabMain.editAuthors.toPlainText() == "Jane Smith\nJohn Smith"
|
||||
assert projEdit.tabMain.spellLang.currentData() == "en"
|
||||
assert projEdit.tabMain.doBackup.isChecked() is False
|
||||
@@ -90,6 +90,7 @@ def testDlgProjSettings_Dialog(
|
||||
projEdit.tabMain.editName.setText("")
|
||||
for c in "Project Name":
|
||||
qtbot.keyClick(projEdit.tabMain.editName, c, delay=typeDelay)
|
||||
projEdit.tabMain.editTitle.setText("")
|
||||
for c in "Project Title":
|
||||
qtbot.keyClick(projEdit.tabMain.editTitle, c, delay=typeDelay)
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import os
|
||||
import pytest
|
||||
|
||||
from shutil import copyfile
|
||||
from tools import cmpFiles
|
||||
from tools import cmpFiles, buildTestProject, XML_IGNORE, writeFile
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtWidgets import QMessageBox, QDialog
|
||||
@@ -32,6 +32,7 @@ from novelwriter.gui import (
|
||||
GuiDocEditor, GuiProjectTree, GuiNovelTree, GuiOutline
|
||||
)
|
||||
from novelwriter.enum import nwItemType, nwWidget
|
||||
from novelwriter.tools import GuiProjectWizard
|
||||
from novelwriter.dialogs.itemeditor import GuiItemEditor
|
||||
|
||||
keyDelay = 2
|
||||
@@ -70,15 +71,52 @@ def testGuiMain_ProjectBlocker(monkeypatch, nwGUI):
|
||||
# END Test testGuiMain_NoProject
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def testGuiMain_NewProject(monkeypatch, nwGUI, fncProj):
|
||||
"""Test creating a new project.
|
||||
"""
|
||||
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
||||
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Yes)
|
||||
|
||||
# No data
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(GuiProjectWizard, "exec_", lambda *a: None)
|
||||
assert nwGUI.newProject(projData=None) is False
|
||||
|
||||
# Close project
|
||||
with monkeypatch.context() as mp:
|
||||
nwGUI.hasProject = True
|
||||
mp.setattr(QMessageBox, "question", lambda *a: QMessageBox.No)
|
||||
assert nwGUI.newProject(projData={"projPath": fncProj}) is False
|
||||
|
||||
# No project path
|
||||
assert nwGUI.newProject(projData={}) is False
|
||||
|
||||
# Project file already exists
|
||||
projFile = os.path.join(fncProj, nwGUI.theProject.projFile)
|
||||
writeFile(projFile, "Stuff")
|
||||
assert nwGUI.newProject(projData={"projPath": fncProj}) is False
|
||||
os.unlink(projFile)
|
||||
|
||||
# An unreachable path should also fail
|
||||
projPath = os.path.join(fncProj, "stuff", "stuff", "stuff")
|
||||
assert nwGUI.newProject(projData={"projPath": projPath}) is False
|
||||
|
||||
# This one should work just fine
|
||||
assert nwGUI.newProject(projData={"projPath": fncProj}) is True
|
||||
assert os.path.isfile(os.path.join(fncProj, nwGUI.theProject.projFile))
|
||||
assert os.path.isdir(os.path.join(fncProj, "content"))
|
||||
|
||||
# END Test testGuiMain_NewProject
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def testGuiMain_ProjectTreeItems(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
|
||||
"""Test handling of project tree items based on GUI focus states.
|
||||
"""
|
||||
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
||||
|
||||
assert nwGUI.newProject({"projPath": fncProj}) is True
|
||||
assert nwGUI.saveProject() is True
|
||||
# assert False
|
||||
buildTestProject(nwGUI, fncProj)
|
||||
|
||||
sHandle = "000000000000f"
|
||||
assert nwGUI.openSelectedItem() is False
|
||||
@@ -139,7 +177,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, fncProj, refDir, outDir, mock
|
||||
monkeypatch.setattr(GuiDocEditor, "hasFocus", lambda *a: True)
|
||||
|
||||
# Create new, save, close project
|
||||
assert nwGUI.newProject({"projPath": fncProj})
|
||||
buildTestProject(nwGUI, fncProj)
|
||||
assert nwGUI.saveProject()
|
||||
assert nwGUI.closeProject()
|
||||
|
||||
@@ -160,7 +198,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, fncProj, refDir, outDir, mock
|
||||
testFile = os.path.join(outDir, "guiEditor_Main_Initial_nwProject.nwx")
|
||||
compFile = os.path.join(refDir, "guiEditor_Main_Initial_nwProject.nwx")
|
||||
copyfile(projFile, testFile)
|
||||
assert cmpFiles(testFile, compFile, [2, 6, 7, 8])
|
||||
assert cmpFiles(testFile, compFile, ignoreStart=XML_IGNORE)
|
||||
qtbot.wait(stepDelay)
|
||||
|
||||
# qtbot.stopForInteraction()
|
||||
@@ -178,9 +216,9 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, fncProj, refDir, outDir, mock
|
||||
assert nwGUI.theProject.projMeta == os.path.join(fncProj, "meta")
|
||||
assert nwGUI.theProject.projFile == "nwProject.nwx"
|
||||
assert nwGUI.theProject.projName == "New Project"
|
||||
assert nwGUI.theProject.bookTitle == ""
|
||||
assert len(nwGUI.theProject.bookAuthors) == 0
|
||||
assert not nwGUI.theProject.spellCheck
|
||||
assert nwGUI.theProject.bookTitle == "New Novel"
|
||||
assert len(nwGUI.theProject.bookAuthors) == 1
|
||||
assert nwGUI.theProject.spellCheck is False
|
||||
|
||||
# Check that tree items have been created
|
||||
assert nwGUI.treeView._getTreeItem("0000000000008") is not None
|
||||
@@ -438,7 +476,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, fncProj, refDir, outDir, mock
|
||||
testFile = os.path.join(outDir, "guiEditor_Main_Final_nwProject.nwx")
|
||||
compFile = os.path.join(refDir, "guiEditor_Main_Final_nwProject.nwx")
|
||||
copyfile(projFile, testFile)
|
||||
assert cmpFiles(testFile, compFile, [2, 6, 7, 8])
|
||||
assert cmpFiles(testFile, compFile, ignoreStart=XML_IGNORE)
|
||||
|
||||
projFile = os.path.join(fncProj, "content", "000000000000f.nwd")
|
||||
testFile = os.path.join(outDir, "guiEditor_Main_Final_000000000000f.nwd")
|
||||
@@ -467,3 +505,52 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, fncProj, refDir, outDir, mock
|
||||
# qtbot.stopForInteraction()
|
||||
|
||||
# END Test testGuiMain_Editing
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def testGuiMain_FocusFullMode(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
|
||||
"""Test toggling focus mode in main window.
|
||||
"""
|
||||
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
||||
|
||||
buildTestProject(nwGUI, fncProj)
|
||||
assert nwGUI.isFocusMode is False
|
||||
|
||||
# Focus Mode
|
||||
# ==========
|
||||
|
||||
# No document open, so not allowing focus mode
|
||||
assert nwGUI.toggleFocusMode() is False
|
||||
|
||||
# Open a file in editor and viewer
|
||||
assert nwGUI.openDocument("000000000000f")
|
||||
assert nwGUI.viewDocument("000000000000f")
|
||||
|
||||
# Enable focus mode
|
||||
assert nwGUI.toggleFocusMode() is True
|
||||
assert nwGUI.treePane.isVisible() is False
|
||||
assert nwGUI.statusBar.isVisible() is False
|
||||
assert nwGUI.mainMenu.isVisible() is False
|
||||
assert nwGUI.viewsBar.isVisible() is False
|
||||
assert nwGUI.splitView.isVisible() is False
|
||||
|
||||
# Disable focus mode
|
||||
assert nwGUI.toggleFocusMode() is True
|
||||
assert nwGUI.treePane.isVisible() is True
|
||||
assert nwGUI.statusBar.isVisible() is True
|
||||
assert nwGUI.mainMenu.isVisible() is True
|
||||
assert nwGUI.viewsBar.isVisible() is True
|
||||
assert nwGUI.splitView.isVisible() is True
|
||||
|
||||
# Full Screen Mode
|
||||
# ================
|
||||
|
||||
assert nwGUI.mainConf.isFullScreen is False
|
||||
nwGUI.toggleFullScreenMode()
|
||||
assert nwGUI.mainConf.isFullScreen is True
|
||||
nwGUI.toggleFullScreenMode()
|
||||
assert nwGUI.mainConf.isFullScreen is False
|
||||
|
||||
# qtbot.stopForInteraction()
|
||||
|
||||
# END Test testGuiMain_FocusFullMode
|
||||
|
||||
@@ -26,7 +26,7 @@ from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QTextCursor, QTextBlock
|
||||
from PyQt5.QtWidgets import QAction, QFileDialog, QMessageBox
|
||||
|
||||
from tools import writeFile
|
||||
from tools import writeFile, buildTestProject
|
||||
|
||||
from novelwriter.gui.doceditor import GuiDocEditor
|
||||
from novelwriter.enum import nwDocAction, nwDocInsert
|
||||
@@ -465,7 +465,7 @@ def testGuiMenu_Insert(qtbot, monkeypatch, nwGUI, fncDir, fncProj, mockRnd):
|
||||
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
||||
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Yes)
|
||||
|
||||
assert nwGUI.newProject({"projPath": fncProj})
|
||||
buildTestProject(nwGUI, fncProj)
|
||||
|
||||
assert nwGUI.treeView._getTreeItem("000000000000f") is not None
|
||||
assert nwGUI.openDocument("000000000000f") is True
|
||||
|
||||
@@ -22,6 +22,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
import pytest
|
||||
import os
|
||||
|
||||
from tools import buildTestProject
|
||||
|
||||
from PyQt5.QtWidgets import QAction, QMessageBox
|
||||
|
||||
from novelwriter.guimain import GuiMain
|
||||
@@ -47,7 +49,7 @@ def testGuiProjTree_NewItems(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockRnd)
|
||||
|
||||
# Create a project
|
||||
prjDir = os.path.join(fncDir, "project")
|
||||
assert nwGUI.newProject({"projPath": prjDir}) is True
|
||||
buildTestProject(nwGUI, prjDir)
|
||||
|
||||
# No itemType set
|
||||
nwTree.clearSelection()
|
||||
@@ -155,7 +157,7 @@ def testGuiProjTree_MoveItems(qtbot, monkeypatch, nwGUI, fncDir, mockRnd):
|
||||
|
||||
# Create a project
|
||||
prjDir = os.path.join(fncDir, "project")
|
||||
assert nwGUI.newProject({"projPath": prjDir}) is True
|
||||
buildTestProject(nwGUI, prjDir)
|
||||
|
||||
# Move Documents
|
||||
# ==============
|
||||
@@ -283,7 +285,7 @@ def testGuiProjTree_DeleteItems(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockR
|
||||
|
||||
# Create a project
|
||||
prjDir = os.path.join(fncDir, "project")
|
||||
assert nwGUI.newProject({"projPath": prjDir}) is True
|
||||
buildTestProject(nwGUI, prjDir)
|
||||
|
||||
# Try emptying the trash already now, when there is no trash folder
|
||||
assert nwTree.emptyTrash() is False
|
||||
|
||||
@@ -22,6 +22,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
import time
|
||||
import pytest
|
||||
|
||||
from tools import buildTestProject
|
||||
|
||||
from PyQt5.QtWidgets import QMessageBox
|
||||
|
||||
from novelwriter.core import NWDoc
|
||||
@@ -34,7 +36,7 @@ def testGuiStatusBar_Main(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
|
||||
"""
|
||||
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
||||
|
||||
assert nwGUI.newProject({"projPath": fncProj}) is True
|
||||
buildTestProject(nwGUI, fncProj)
|
||||
cHandle = nwGUI.theProject.newFile("A Note", "000000000000a")
|
||||
newDoc = NWDoc(nwGUI.theProject, cHandle)
|
||||
newDoc.writeDocument("# A Note\n\n")
|
||||
@@ -89,10 +91,10 @@ def testGuiStatusBar_Main(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
|
||||
# Project Stats
|
||||
nwGUI.statusBar.mainConf.incNotesWCount = False
|
||||
nwGUI._updateStatusWordCount()
|
||||
assert nwGUI.statusBar.statsText.text() == "Words: 6 (+6)"
|
||||
assert nwGUI.statusBar.statsText.text() == "Words: 9 (+9)"
|
||||
nwGUI.statusBar.mainConf.incNotesWCount = True
|
||||
nwGUI._updateStatusWordCount()
|
||||
assert nwGUI.statusBar.statsText.text() == "Words: 8 (+8)"
|
||||
assert nwGUI.statusBar.statsText.text() == "Words: 11 (+11)"
|
||||
|
||||
# qtbot.stopForInteraction()
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
from tools import getGuiItem
|
||||
from tools import getGuiItem, buildTestProject
|
||||
|
||||
from PyQt5.QtWidgets import QAction, QMessageBox
|
||||
|
||||
@@ -40,7 +40,7 @@ def testToolLipsum_Main(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
|
||||
assert getGuiItem("GuiLipsum") is None
|
||||
|
||||
# Create a new project
|
||||
assert nwGUI.newProject({"projPath": fncProj}) is True
|
||||
buildTestProject(nwGUI, fncProj)
|
||||
assert nwGUI.openDocument("000000000000f") is True
|
||||
assert len(nwGUI.docEditor.getText()) == 15
|
||||
|
||||
|
||||
@@ -205,14 +205,11 @@ def testToolProjectWizard_Run(qtbot, monkeypatch, nwGUI, fncDir, prjType):
|
||||
customPage.addPlot.setChecked(True)
|
||||
customPage.addChar.setChecked(True)
|
||||
customPage.addWorld.setChecked(True)
|
||||
customPage.addTime.setChecked(True)
|
||||
customPage.addObject.setChecked(True)
|
||||
customPage.addEntity.setChecked(True)
|
||||
customPage.addNotes.setChecked(True)
|
||||
|
||||
if prjType == "custom2":
|
||||
customPage.numChapters.setValue(0)
|
||||
customPage.numScenes.setValue(10)
|
||||
customPage.chFolders.setChecked(False)
|
||||
|
||||
qtbot.wait(stepDelay)
|
||||
qtbot.mouseClick(nwWiz.button(QWizard.NextButton), Qt.LeftButton)
|
||||
@@ -240,23 +237,20 @@ def testToolProjectWizard_Run(qtbot, monkeypatch, nwGUI, fncDir, prjType):
|
||||
nwItemClass.PLOT,
|
||||
nwItemClass.CHARACTER,
|
||||
nwItemClass.WORLD,
|
||||
nwItemClass.TIMELINE,
|
||||
nwItemClass.OBJECT,
|
||||
nwItemClass.ENTITY,
|
||||
]
|
||||
if prjType == "custom1":
|
||||
assert projData["numChapters"] == 5
|
||||
assert projData["numScenes"] == 5
|
||||
assert projData["chFolders"]
|
||||
assert projData["addNotes"] is True
|
||||
else:
|
||||
assert projData["numChapters"] == 0
|
||||
assert projData["numScenes"] == 10
|
||||
assert not projData["chFolders"]
|
||||
assert projData["addNotes"] is True
|
||||
else:
|
||||
assert projData["addRoots"] == []
|
||||
assert projData["numChapters"] == 0
|
||||
assert projData["numScenes"] == 0
|
||||
assert not projData["chFolders"]
|
||||
assert projData["addNotes"] is False
|
||||
|
||||
# Cleanup
|
||||
nwWiz.reject()
|
||||
|
||||
@@ -23,8 +23,8 @@ import pytest
|
||||
import json
|
||||
import os
|
||||
|
||||
from tools import getGuiItem, writeFile
|
||||
from mock import causeOSError
|
||||
from tools import getGuiItem, writeFile, buildTestProject
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtWidgets import QAction, QFileDialog, QMessageBox
|
||||
@@ -48,7 +48,7 @@ def testToolWritingStats_Main(qtbot, monkeypatch, nwGUI, fncDir, fncProj):
|
||||
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Yes)
|
||||
|
||||
# Create a project to work on
|
||||
assert nwGUI.newProject({"projPath": fncProj})
|
||||
buildTestProject(nwGUI, fncProj)
|
||||
qtbot.wait(100)
|
||||
assert nwGUI.saveProject()
|
||||
sessFile = os.path.join(fncProj, "meta", nwFiles.SESS_STATS)
|
||||
|
||||
@@ -20,10 +20,13 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import os
|
||||
import time
|
||||
import shutil
|
||||
|
||||
from PyQt5.QtWidgets import qApp
|
||||
|
||||
XML_IGNORE = ("<novelWriterXML", "<saveCount", "<autoCount", "<editTime")
|
||||
|
||||
|
||||
def cmpFiles(fileOne, fileTwo, ignoreLines=None, ignoreStart=None):
|
||||
"""Compare two files, but optionally ignore lines given by a list.
|
||||
@@ -119,3 +122,56 @@ def cleanProject(projPath):
|
||||
os.unlink(tocFile)
|
||||
|
||||
return
|
||||
|
||||
|
||||
def buildTestProject(theObject, projPath):
|
||||
"""Build a standard test project in projPath using theProject
|
||||
object as the parent.
|
||||
"""
|
||||
from novelwriter.enum import nwItemClass
|
||||
from novelwriter.core import NWProject, NWDoc
|
||||
|
||||
if isinstance(theObject, NWProject):
|
||||
theGUI = None
|
||||
theProject = theObject
|
||||
else:
|
||||
theGUI = theObject
|
||||
theProject = theObject.theProject
|
||||
|
||||
theProject.clearProject()
|
||||
theProject.setProjectPath(projPath, newProject=True)
|
||||
theProject.setProjectName("New Project")
|
||||
theProject.setBookTitle("New Novel")
|
||||
theProject.setBookAuthors("Jane Doe")
|
||||
|
||||
# Creating a minimal project with a few root folders and a
|
||||
# single chapter folder with a single file.
|
||||
xHandle = {}
|
||||
xHandle[1] = theProject.newRoot(nwItemClass.NOVEL, "Novel")
|
||||
xHandle[2] = theProject.newRoot(nwItemClass.PLOT, "Plot")
|
||||
xHandle[3] = theProject.newRoot(nwItemClass.CHARACTER, "Characters")
|
||||
xHandle[4] = theProject.newRoot(nwItemClass.WORLD, "World")
|
||||
xHandle[5] = theProject.newFile("Title Page", xHandle[1])
|
||||
xHandle[6] = theProject.newFolder("New Chapter", xHandle[1])
|
||||
xHandle[7] = theProject.newFile("New Chapter", xHandle[6])
|
||||
xHandle[8] = theProject.newFile("New Scene", xHandle[6])
|
||||
|
||||
aDoc = NWDoc(theProject, xHandle[5])
|
||||
aDoc.writeDocument("#! New Novel\n\n>> By Jane DOe <<\n")
|
||||
|
||||
aDoc = NWDoc(theProject, xHandle[7])
|
||||
aDoc.writeDocument("## %s\n\n" % theProject.tr("New Chapter"))
|
||||
|
||||
aDoc = NWDoc(theProject, xHandle[8])
|
||||
aDoc.writeDocument("### %s\n\n" % theProject.tr("New Scene"))
|
||||
|
||||
theProject.projOpened = time.time()
|
||||
theProject.setProjectChanged(True)
|
||||
theProject.saveProject(autoSave=True)
|
||||
|
||||
if theGUI is not None:
|
||||
theGUI.hasProject = True
|
||||
theGUI.rebuildTrees()
|
||||
theGUI.rebuildIndex(beQuiet=True)
|
||||
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user