diff --git a/novelwriter/core/project.py b/novelwriter/core/project.py
index 26efb323..3341e578 100644
--- a/novelwriter/core/project.py
+++ b/novelwriter/core/project.py
@@ -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:
diff --git a/novelwriter/gui/projtree.py b/novelwriter/gui/projtree.py
index 0339ec5f..5d40aeae 100644
--- a/novelwriter/gui/projtree.py
+++ b/novelwriter/gui/projtree.py
@@ -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):
diff --git a/novelwriter/guimain.py b/novelwriter/guimain.py
index ad06cc59..724989f9 100644
--- a/novelwriter/guimain.py
+++ b/novelwriter/guimain.py
@@ -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
diff --git a/novelwriter/tools/projwizard.py b/novelwriter/tools/projwizard.py
index e4cc6862..765445b9 100644
--- a/novelwriter/tools/projwizard.py
+++ b/novelwriter/tools/projwizard.py
@@ -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(
- "
%s
%s
" % (
- 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(
+ "%s
• %s
%s
" % (
+ self.tr("You have selected the following:"),
+ "
• ".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
diff --git a/tests/reference/coreProject_NewCustomA_nwProject.nwx b/tests/reference/coreProject_NewCustomA_nwProject.nwx
index 14abf9e2..be4845bf 100644
--- a/tests/reference/coreProject_NewCustomA_nwProject.nwx
+++ b/tests/reference/coreProject_NewCustomA_nwProject.nwx
@@ -1,5 +1,5 @@
-
+
Test Custom
Test Novel
@@ -29,110 +29,106 @@
- New
+ New
Note
Draft
Finished
- New
+ New
Minor
Major
Main
-
+
-
Novel
- -
-
- Plot
-
- -
-
- Characters
-
- -
-
- Locations
-
- -
-
- Timeline
-
- -
-
- Objects
-
- -
-
- Entities
-
- -
+
-
Title Page
- -
-
- Chapter 1
-
- -
+
-
Chapter 1
- -
+
-
Scene 1.1
- -
+
-
Scene 1.2
- -
+
-
Scene 1.3
- -
-
- Chapter 2
-
- -
+
-
Chapter 2
- -
+
-
Scene 2.1
- -
+
-
Scene 2.2
- -
+
-
Scene 2.3
- -
-
- Chapter 3
-
- -
+
-
Chapter 3
- -
+
-
Scene 3.1
- -
+
-
Scene 3.2
- -
+
-
Scene 3.3
+ -
+
+ Plot
+
+ -
+
+ Main Plot
+
+ -
+
+ Characters
+
+ -
+
+ Protagonist
+
+ -
+
+ Locations
+
+ -
+
+ Main Location
+
+ -
+
+ Archive
+
+ -
+
+ Trash
+
diff --git a/tests/reference/coreProject_NewCustomB_nwProject.nwx b/tests/reference/coreProject_NewCustomB_nwProject.nwx
index bca6ea80..12f911cd 100644
--- a/tests/reference/coreProject_NewCustomB_nwProject.nwx
+++ b/tests/reference/coreProject_NewCustomB_nwProject.nwx
@@ -1,5 +1,5 @@
-
+
Test Custom
Test Novel
@@ -29,74 +29,82 @@
- New
+ New
Note
Draft
Finished
- New
+ New
Minor
Major
Main
-
+
-
Novel
- -
-
- Plot
-
- -
-
- Characters
-
- -
-
- Locations
-
- -
-
- Timeline
-
- -
-
- Objects
-
- -
-
- Entities
-
- -
+
-
Title Page
- -
+
-
Scene 1
- -
+
-
Scene 2
- -
+
-
Scene 3
- -
+
-
Scene 4
- -
+
-
Scene 5
- -
+
-
Scene 6
+ -
+
+ Plot
+
+ -
+
+ Main Plot
+
+ -
+
+ Characters
+
+ -
+
+ Protagonist
+
+ -
+
+ Locations
+
+ -
+
+ Main Location
+
+ -
+
+ Archive
+
+ -
+
+ Trash
+
diff --git a/tests/reference/coreProject_NewFile_nwProject.nwx b/tests/reference/coreProject_NewFile_nwProject.nwx
index d253ebcc..19a2f4bf 100644
--- a/tests/reference/coreProject_NewFile_nwProject.nwx
+++ b/tests/reference/coreProject_NewFile_nwProject.nwx
@@ -1,8 +1,9 @@
-
+
New Project
-
+ New Novel
+ Jane Doe
2
1
0
diff --git a/tests/reference/coreProject_NewMinimal_nwProject.nwx b/tests/reference/coreProject_NewMinimal_nwProject.nwx
index a6711a84..422bb6b2 100644
--- a/tests/reference/coreProject_NewMinimal_nwProject.nwx
+++ b/tests/reference/coreProject_NewMinimal_nwProject.nwx
@@ -1,5 +1,5 @@
-
+
New Project
@@ -44,33 +44,33 @@
Novel
- -
-
- Plot
-
- -
-
- Characters
-
- -
-
- World
-
- -
+
-
Title Page
- -
-
- New Chapter
-
- -
+
-
New Chapter
- -
+
-
New Scene
+ -
+
+ Plot
+
+ -
+
+ Characters
+
+ -
+
+ Locations
+
+ -
+
+ Archive
+
diff --git a/tests/reference/coreProject_NewRoot_nwProject.nwx b/tests/reference/coreProject_NewRoot_nwProject.nwx
index 2ab62301..cd25c1cf 100644
--- a/tests/reference/coreProject_NewRoot_nwProject.nwx
+++ b/tests/reference/coreProject_NewRoot_nwProject.nwx
@@ -1,8 +1,9 @@
-
+
New Project
-
+ New Novel
+ Jane Doe
2
1
0
@@ -82,11 +83,11 @@
-
- Character
+ Characters
-
- World
+ Locations
-
@@ -94,15 +95,15 @@
-
- Object
+ Objects
-
- Custom1
+ Custom
-
- Custom2
+ Custom
diff --git a/tests/reference/guiEditor_Main_Final_nwProject.nwx b/tests/reference/guiEditor_Main_Final_nwProject.nwx
index c4ba847c..a47d454d 100644
--- a/tests/reference/guiEditor_Main_Final_nwProject.nwx
+++ b/tests/reference/guiEditor_Main_Final_nwProject.nwx
@@ -1,9 +1,10 @@
-
+
New Project
-
- 5
+ New Novel
+ Jane Doe
+ 4
2
3
@@ -15,8 +16,8 @@
True
000000000000f
None
- 126
- 99
+ 129
+ 102
27
@@ -45,7 +46,7 @@
Novel
-
-
+
Title Page
-
diff --git a/tests/reference/guiEditor_Main_Initial_nwProject.nwx b/tests/reference/guiEditor_Main_Initial_nwProject.nwx
index 1a5fd5be..03313570 100644
--- a/tests/reference/guiEditor_Main_Initial_nwProject.nwx
+++ b/tests/reference/guiEditor_Main_Initial_nwProject.nwx
@@ -1,9 +1,10 @@
-
+
New Project
-
- 3
+ New Novel
+ Jane Doe
+ 2
1
0
@@ -15,8 +16,8 @@
True
None
None
- 6
- 6
+ 9
+ 9
0
@@ -45,7 +46,7 @@
Novel
-
-
+
Title Page
-
diff --git a/tests/reference/guiProjSettings_Dialog_nwProject.nwx b/tests/reference/guiProjSettings_Dialog_nwProject.nwx
index 326c63e5..f12c1dc2 100644
--- a/tests/reference/guiProjSettings_Dialog_nwProject.nwx
+++ b/tests/reference/guiProjSettings_Dialog_nwProject.nwx
@@ -1,11 +1,11 @@
-
+
Project Name
Project Title
Jane Doe
John Doh
- 2
+ 1
1
0
@@ -17,8 +17,8 @@
True
None
None
- 6
- 6
+ 9
+ 9
0
B
@@ -51,7 +51,7 @@
Novel
-
-
+
Title Page
-
diff --git a/tests/test_core/test_core_index.py b/tests/test_core/test_core_index.py
index c3e6ef47..93ec35c6 100644
--- a/tests/test_core/test_core_index.py
+++ b/tests/test_core/test_core_index.py
@@ -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)
diff --git a/tests/test_core/test_core_project.py b/tests/test_core/test_core_project.py
index 55c18e65..e6e5092d 100644
--- a/tests/test_core/test_core_project.py
+++ b/tests/test_core/test_core_project.py
@@ -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")
diff --git a/tests/test_dialogs/test_dlg_docmerge.py b/tests/test_dialogs/test_dlg_docmerge.py
index f635be4a..a82c77bd 100644
--- a/tests/test_dialogs/test_dlg_docmerge.py
+++ b/tests/test_dialogs/test_dlg_docmerge.py
@@ -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"
diff --git a/tests/test_dialogs/test_dlg_docsplit.py b/tests/test_dialogs/test_dlg_docsplit.py
index 19988c0b..90e3375d 100644
--- a/tests/test_dialogs/test_dlg_docsplit.py
+++ b/tests/test_dialogs/test_dlg_docsplit.py
@@ -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"
diff --git a/tests/test_dialogs/test_dlg_itemeditor.py b/tests/test_dialogs/test_dlg_itemeditor.py
index ebd71d6c..c221138e 100644
--- a/tests/test_dialogs/test_dlg_itemeditor.py
+++ b/tests/test_dialogs/test_dlg_itemeditor.py
@@ -21,7 +21,7 @@ along with this program. If not, see .
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")
diff --git a/tests/test_dialogs/test_dlg_projsettings.py b/tests/test_dialogs/test_dlg_projsettings.py
index 54827cfd..f193194a 100644
--- a/tests/test_dialogs/test_dlg_projsettings.py
+++ b/tests/test_dialogs/test_dlg_projsettings.py
@@ -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)
diff --git a/tests/test_gui/test_gui_guimain.py b/tests/test_gui/test_gui_guimain.py
index ddb4f09b..e0d7e2ec 100644
--- a/tests/test_gui/test_gui_guimain.py
+++ b/tests/test_gui/test_gui_guimain.py
@@ -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
diff --git a/tests/test_gui/test_gui_mainmenu.py b/tests/test_gui/test_gui_mainmenu.py
index 815c8566..801abd68 100644
--- a/tests/test_gui/test_gui_mainmenu.py
+++ b/tests/test_gui/test_gui_mainmenu.py
@@ -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
diff --git a/tests/test_gui/test_gui_projtree.py b/tests/test_gui/test_gui_projtree.py
index af851138..5d3354f9 100644
--- a/tests/test_gui/test_gui_projtree.py
+++ b/tests/test_gui/test_gui_projtree.py
@@ -22,6 +22,8 @@ along with this program. If not, see .
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
diff --git a/tests/test_gui/test_gui_statusbar.py b/tests/test_gui/test_gui_statusbar.py
index 8993a2e8..51e9c70b 100644
--- a/tests/test_gui/test_gui_statusbar.py
+++ b/tests/test_gui/test_gui_statusbar.py
@@ -22,6 +22,8 @@ along with this program. If not, see .
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()
diff --git a/tests/test_tools/test_tools_lipsum.py b/tests/test_tools/test_tools_lipsum.py
index 7d6c08f9..629deb56 100644
--- a/tests/test_tools/test_tools_lipsum.py
+++ b/tests/test_tools/test_tools_lipsum.py
@@ -21,7 +21,7 @@ along with this program. If not, see .
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
diff --git a/tests/test_tools/test_tools_projwizard.py b/tests/test_tools/test_tools_projwizard.py
index ef4c31cd..8839964e 100644
--- a/tests/test_tools/test_tools_projwizard.py
+++ b/tests/test_tools/test_tools_projwizard.py
@@ -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()
diff --git a/tests/test_tools/test_tools_writingstats.py b/tests/test_tools/test_tools_writingstats.py
index cffef9e6..b7358b20 100644
--- a/tests/test_tools/test_tools_writingstats.py
+++ b/tests/test_tools/test_tools_writingstats.py
@@ -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)
diff --git a/tests/tools.py b/tests/tools.py
index bd417aae..fcdd3817 100644
--- a/tests/tools.py
+++ b/tests/tools.py
@@ -20,10 +20,13 @@ along with this program. If not, see .
"""
import os
+import time
import shutil
from PyQt5.QtWidgets import qApp
+XML_IGNORE = ("> 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