Update the new project code and add title page
This commit is contained in:
+173
-186
@@ -171,179 +171,6 @@ class NWProject():
|
||||
# Project Methods
|
||||
##
|
||||
|
||||
def newProject(self, projData={}):
|
||||
"""Create a new project by populating the project tree with a
|
||||
few starter items.
|
||||
"""
|
||||
popMinimal = True
|
||||
popCustom = False
|
||||
popSample = False
|
||||
if "popMinimal" in projData:
|
||||
popMinimal = projData["popMinimal"]
|
||||
if "popCustom" in projData:
|
||||
popCustom = projData["popCustom"]
|
||||
if "popSample" in projData:
|
||||
popSample = projData["popSample"]
|
||||
|
||||
# Check if we're extracting the sample project.
|
||||
# This is handled differently as it isn't actually a new project.
|
||||
if popSample:
|
||||
return self.extractSampleProject(projData)
|
||||
|
||||
# Set the project path
|
||||
if "projPath" in projData:
|
||||
self.setProjectPath(projData["projPath"], newProject=True)
|
||||
else:
|
||||
logger.error("No project path set for the new project")
|
||||
return False
|
||||
|
||||
# Project Title and Authors
|
||||
if "projName" in projData:
|
||||
self.setProjectName(projData["projName"])
|
||||
else:
|
||||
self.setProjectName("New Project")
|
||||
if "projTitle" in projData:
|
||||
self.setBookTitle(projData["projTitle"])
|
||||
if "projAuthors" in projData:
|
||||
self.setBookAuthors(projData["projAuthors"])
|
||||
|
||||
if popMinimal:
|
||||
# Creating a minimal project with a few root folders, a
|
||||
# single chapter folder with a single file.
|
||||
hNovel = self.newRoot("Novel", nwItemClass.NOVEL)
|
||||
hChars = self.newRoot("Characters", nwItemClass.CHARACTER)
|
||||
hWorld = self.newRoot("Plot", nwItemClass.PLOT)
|
||||
hWorld = self.newRoot("World", nwItemClass.WORLD)
|
||||
hChapF = self.newFolder("New Chapter", nwItemClass.NOVEL, hNovel)
|
||||
hScene = self.newFile("New Scene", nwItemClass.NOVEL, hChapF)
|
||||
|
||||
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
|
||||
hNovel = self.newRoot("Novel", nwItemClass.NOVEL)
|
||||
if "addRoots" in projData:
|
||||
for newRoot in projData["addRoots"]:
|
||||
if newRoot in nwItemClass:
|
||||
self.newRoot(nwLabels.CLASS_NAME[newRoot], newRoot)
|
||||
|
||||
# Create Chapters and Scenes
|
||||
numChapters = 0
|
||||
numScenes = 0
|
||||
chFolders = False
|
||||
if "numChapters" in projData:
|
||||
numChapters = projData["numChapters"]
|
||||
if "numScenes" in projData:
|
||||
numScenes = projData["numScenes"]
|
||||
if "chFolders" in projData:
|
||||
chFolders = projData["chFolders"]
|
||||
|
||||
# Create Chapters
|
||||
if numChapters > 0:
|
||||
for ch in range(numChapters):
|
||||
chTitle = "Chapter %d" % (ch+1)
|
||||
hParDir = hNovel
|
||||
if chFolders:
|
||||
hParDir = self.newFolder(chTitle, nwItemClass.NOVEL, hNovel)
|
||||
hChapD = self.newFile(chTitle, nwItemClass.NOVEL, hParDir)
|
||||
chItem = self.projTree[hChapD]
|
||||
if hChapD is None:
|
||||
logger.error("Something went wrong when creating chapter file.")
|
||||
continue
|
||||
chItem.setLayout(nwItemLayout.CHAPTER)
|
||||
|
||||
# Create Chapter > Scenes
|
||||
if numScenes > 0:
|
||||
for sc in range(numScenes):
|
||||
scTitle = "Scene %d.%d" % (ch+1, sc+1)
|
||||
hScene = self.newFile(scTitle, nwItemClass.NOVEL, hParDir)
|
||||
|
||||
# Create Scenes (No Chapters)
|
||||
elif numScenes > 0:
|
||||
for sc in range(numScenes):
|
||||
scTitle = "Scene %d" % (sc+1)
|
||||
hScene = self.newFile(scTitle, nwItemClass.NOVEL, hNovel)
|
||||
|
||||
else:
|
||||
# Fallback just in case.
|
||||
self.newRoot("Novel", nwItemClass.NOVEL)
|
||||
|
||||
# Finalise
|
||||
self.projOpened = time()
|
||||
self.setProjectChanged(True)
|
||||
self.saveProject(autoSave=True)
|
||||
|
||||
return True
|
||||
|
||||
def extractSampleProject(self, projData):
|
||||
"""Make a copy of the sample project.
|
||||
First, try to copy the content of the sample folder to the new
|
||||
project path, or if the folder doesn't exist, look for the zip
|
||||
file in the assets folder.
|
||||
"""
|
||||
if "projName" in projData:
|
||||
projName = projData["projName"]
|
||||
else:
|
||||
projName = "Sample Project"
|
||||
|
||||
if "projPath" in projData:
|
||||
projPath = projData["projPath"]
|
||||
else:
|
||||
logger.error("No project path set for the example project")
|
||||
return False
|
||||
|
||||
srcSample = path.abspath(path.join(self.mainConf.appRoot, "sample"))
|
||||
pkgSample = path.join(self.mainConf.assetPath, "sample.zip")
|
||||
|
||||
isSuccess = False
|
||||
if path.isfile(pkgSample):
|
||||
|
||||
self.setProjectPath(projPath, newProject=True)
|
||||
try:
|
||||
unpack_archive(pkgSample, projPath)
|
||||
isSuccess = True
|
||||
except Exception as e:
|
||||
self.makeAlert(
|
||||
["Failed to create a new example project.", str(e)], nwAlert.ERROR
|
||||
)
|
||||
|
||||
elif path.isdir(srcSample):
|
||||
|
||||
self.setProjectPath(projPath, newProject=True)
|
||||
try:
|
||||
srcProj = path.join(srcSample, nwFiles.PROJ_FILE)
|
||||
dstProj = path.join(projPath, nwFiles.PROJ_FILE)
|
||||
copyfile(srcProj, dstProj)
|
||||
|
||||
srcContent = path.join(srcSample, "content")
|
||||
dstContent = path.join(projPath, "content")
|
||||
for srcFile in listdir(srcContent):
|
||||
srcDoc = path.join(srcContent, srcFile)
|
||||
dstDoc = path.join(dstContent, srcFile)
|
||||
copyfile(srcDoc, dstDoc)
|
||||
|
||||
isSuccess = True
|
||||
|
||||
except Exception as e:
|
||||
self.makeAlert(
|
||||
["Failed to create a new example project.", str(e)], nwAlert.ERROR
|
||||
)
|
||||
|
||||
else:
|
||||
self.makeAlert((
|
||||
"Failed to create a new example project. "
|
||||
"Could not find the necessary files."
|
||||
), nwAlert.ERROR)
|
||||
|
||||
if isSuccess:
|
||||
self.clearProject()
|
||||
self.theParent.openProject(projPath)
|
||||
self.theParent.rebuildIndex()
|
||||
|
||||
return isSuccess
|
||||
|
||||
def clearProject(self):
|
||||
"""Clear the data for the current project, and set them to
|
||||
default values.
|
||||
@@ -379,15 +206,15 @@ class NWProject():
|
||||
self.spellCheck = False
|
||||
self.autoOutline = True
|
||||
self.statusItems = NWStatus()
|
||||
self.statusItems.addEntry("New", (100,100,100))
|
||||
self.statusItems.addEntry("Note", (200, 50, 0))
|
||||
self.statusItems.addEntry("Draft", (200,150, 0))
|
||||
self.statusItems.addEntry("Finished",( 50,200, 0))
|
||||
self.statusItems.addEntry("New", (100, 100, 100))
|
||||
self.statusItems.addEntry("Note", (200, 50, 0))
|
||||
self.statusItems.addEntry("Draft", (200, 150, 0))
|
||||
self.statusItems.addEntry("Finished",( 50, 200, 0))
|
||||
self.importItems = NWStatus()
|
||||
self.importItems.addEntry("New", (100,100,100))
|
||||
self.importItems.addEntry("Minor", (200, 50, 0))
|
||||
self.importItems.addEntry("Major", (200,150, 0))
|
||||
self.importItems.addEntry("Main", ( 50,200, 0))
|
||||
self.importItems.addEntry("New", (100, 100, 100))
|
||||
self.importItems.addEntry("Minor", (200, 50, 0))
|
||||
self.importItems.addEntry("Major", (200, 150, 0))
|
||||
self.importItems.addEntry("Main", ( 50, 200, 0))
|
||||
self.lastEdited = None
|
||||
self.lastViewed = None
|
||||
self.lastWCount = 0
|
||||
@@ -397,6 +224,104 @@ class NWProject():
|
||||
|
||||
return
|
||||
|
||||
def newProject(self, projData={}):
|
||||
"""Create a new project by populating the project tree with a
|
||||
few starter items.
|
||||
"""
|
||||
popMinimal = projData.get("popMinimal", True)
|
||||
popCustom = projData.get("popCustom", False)
|
||||
popSample = projData.get("popSample", False)
|
||||
|
||||
# Check if we're extracting the sample project. This is handled
|
||||
# differently as it isn't actually a new project, so we forward
|
||||
# this to another function and return here.
|
||||
if popSample:
|
||||
return self.extractSampleProject(projData)
|
||||
|
||||
# Project Settings
|
||||
projPath = projData.get("projPath", None)
|
||||
projName = projData.get("projName", "New Project")
|
||||
projTitle = projData.get("projTitle", "")
|
||||
projAuthors = projData.get("projAuthors", "")
|
||||
|
||||
if projPath is None:
|
||||
logger.error("No project path set for the new project")
|
||||
return False
|
||||
|
||||
if not self.setProjectPath(projPath, newProject=True):
|
||||
return False
|
||||
|
||||
self.setProjectName(projName)
|
||||
self.setBookTitle(projTitle)
|
||||
self.setBookAuthors(projAuthors)
|
||||
|
||||
if popMinimal:
|
||||
# Creating a minimal project with a few root folders and a
|
||||
# single chapter folder with a single file.
|
||||
nHandle = self.newRoot("Novel", nwItemClass.NOVEL)
|
||||
xHandle = self.newRoot("Plot", nwItemClass.PLOT)
|
||||
xHandle = self.newRoot("Characters", nwItemClass.CHARACTER)
|
||||
xHandle = self.newRoot("World", nwItemClass.WORLD)
|
||||
tHandle = self.newFile("Title Page", nwItemClass.NOVEL, nHandle)
|
||||
cHandle = self.newFolder("New Chapter", nwItemClass.NOVEL, nHandle)
|
||||
fHandle = self.newFile("New Chapter", nwItemClass.NOVEL, cHandle)
|
||||
XHandle = self.newFile("New Scene", nwItemClass.NOVEL, cHandle)
|
||||
self.projTree.setFileItemLayout(tHandle, nwItemLayout.TITLE)
|
||||
self.projTree.setFileItemLayout(fHandle, nwItemLayout.CHAPTER)
|
||||
|
||||
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("Novel", nwItemClass.NOVEL)
|
||||
for newRoot in projData.get("addRoots", []):
|
||||
if newRoot in nwItemClass:
|
||||
self.newRoot(nwLabels.CLASS_NAME[newRoot], newRoot)
|
||||
|
||||
# Create a title page
|
||||
tHandle = self.newFile("Title Page", nwItemClass.NOVEL, nHandle)
|
||||
self.projTree.setFileItemLayout(tHandle, nwItemLayout.TITLE)
|
||||
|
||||
# Create chapters and scenes
|
||||
numChapters = projData.get("numChapters", 0)
|
||||
numScenes = projData.get("numScenes", 0)
|
||||
chFolders = projData.get("chFolders", False)
|
||||
|
||||
# Create chapters
|
||||
if numChapters > 0:
|
||||
for ch in range(numChapters):
|
||||
chTitle = "Chapter %d" % (ch+1)
|
||||
pHandle = nHandle
|
||||
if chFolders:
|
||||
pHandle = self.newFolder(chTitle, nwItemClass.NOVEL, nHandle)
|
||||
cHandle = self.newFile(chTitle, nwItemClass.NOVEL, pHandle)
|
||||
self.projTree.setFileItemLayout(cHandle, nwItemLayout.CHAPTER)
|
||||
|
||||
# Create chapter scenes
|
||||
if numScenes > 0:
|
||||
for sc in range(numScenes):
|
||||
scTitle = "Scene %d.%d" % (ch+1, sc+1)
|
||||
sHandle = self.newFile(scTitle, nwItemClass.NOVEL, pHandle)
|
||||
|
||||
# Create scenes (no chapters)
|
||||
elif numScenes > 0:
|
||||
for sc in range(numScenes):
|
||||
scTitle = "Scene %d" % (sc+1)
|
||||
sHandle = self.newFile(scTitle, nwItemClass.NOVEL, nHandle)
|
||||
|
||||
else:
|
||||
# Fallback just in case. We shouldn't reach here.
|
||||
self.newRoot("Novel", nwItemClass.NOVEL)
|
||||
|
||||
# Finalise
|
||||
self.projOpened = time()
|
||||
self.setProjectChanged(True)
|
||||
self.saveProject(autoSave=True)
|
||||
|
||||
return True
|
||||
|
||||
def openProject(self, fileName, overrideLock=False):
|
||||
"""Open the project file provided, or if doesn't exist, assume
|
||||
it is a folder, and look for the file within it. If successful,
|
||||
@@ -716,9 +641,9 @@ class NWProject():
|
||||
if len(aKey) > 0:
|
||||
self._packProjectValue(xTitleFmt, aKey, aValue)
|
||||
|
||||
xStatus = etree.SubElement(xSettings,"status")
|
||||
xStatus = etree.SubElement(xSettings, "status")
|
||||
self.statusItems.packEntries(xStatus)
|
||||
xStatus = etree.SubElement(xSettings,"importance")
|
||||
xStatus = etree.SubElement(xSettings, "importance")
|
||||
self.importItems.packEntries(xStatus)
|
||||
|
||||
# Save Tree Content
|
||||
@@ -733,8 +658,8 @@ class NWProject():
|
||||
with open(tempFile, mode="wb") as outFile:
|
||||
outFile.write(etree.tostring(
|
||||
nwXML,
|
||||
pretty_print = True,
|
||||
encoding = "utf-8",
|
||||
pretty_print = True,
|
||||
encoding = "utf-8",
|
||||
xml_declaration = True
|
||||
))
|
||||
except Exception as e:
|
||||
@@ -794,7 +719,7 @@ class NWProject():
|
||||
return True
|
||||
|
||||
##
|
||||
# Backup Project
|
||||
# Zip/Unzip Project
|
||||
##
|
||||
|
||||
def zipIt(self, doNotify):
|
||||
@@ -870,6 +795,68 @@ class NWProject():
|
||||
|
||||
return True
|
||||
|
||||
def extractSampleProject(self, projData):
|
||||
"""Make a copy of the sample project.
|
||||
First, try to copy the content of the sample folder to the new
|
||||
project path, or if the folder doesn't exist, look for the zip
|
||||
file in the assets folder.
|
||||
"""
|
||||
projName = projData.get("projName", "Sample Project")
|
||||
projPath = projData.get("projPath", None)
|
||||
if projPath is None:
|
||||
logger.error("No project path set for the example project")
|
||||
return False
|
||||
|
||||
srcSample = path.abspath(path.join(self.mainConf.appRoot, "sample"))
|
||||
pkgSample = path.join(self.mainConf.assetPath, "sample.zip")
|
||||
|
||||
isSuccess = False
|
||||
if path.isfile(pkgSample):
|
||||
|
||||
self.setProjectPath(projPath, newProject=True)
|
||||
try:
|
||||
unpack_archive(pkgSample, projPath)
|
||||
isSuccess = True
|
||||
except Exception as e:
|
||||
self.makeAlert(
|
||||
["Failed to create a new example project.", str(e)], nwAlert.ERROR
|
||||
)
|
||||
|
||||
elif path.isdir(srcSample):
|
||||
|
||||
self.setProjectPath(projPath, newProject=True)
|
||||
try:
|
||||
srcProj = path.join(srcSample, nwFiles.PROJ_FILE)
|
||||
dstProj = path.join(projPath, nwFiles.PROJ_FILE)
|
||||
copyfile(srcProj, dstProj)
|
||||
|
||||
srcContent = path.join(srcSample, "content")
|
||||
dstContent = path.join(projPath, "content")
|
||||
for srcFile in listdir(srcContent):
|
||||
srcDoc = path.join(srcContent, srcFile)
|
||||
dstDoc = path.join(dstContent, srcFile)
|
||||
copyfile(srcDoc, dstDoc)
|
||||
|
||||
isSuccess = True
|
||||
|
||||
except Exception as e:
|
||||
self.makeAlert(
|
||||
["Failed to create a new example project.", str(e)], nwAlert.ERROR
|
||||
)
|
||||
|
||||
else:
|
||||
self.makeAlert((
|
||||
"Failed to create a new example project. "
|
||||
"Could not find the necessary files."
|
||||
), nwAlert.ERROR)
|
||||
|
||||
if isSuccess:
|
||||
self.clearProject()
|
||||
self.theParent.openProject(projPath)
|
||||
self.theParent.rebuildIndex()
|
||||
|
||||
return isSuccess
|
||||
|
||||
##
|
||||
# Setters
|
||||
##
|
||||
|
||||
@@ -314,6 +314,22 @@ class NWTree():
|
||||
self._handleSeed = theSeed
|
||||
return
|
||||
|
||||
def setFileItemLayout(self, tHandle, itemLayout):
|
||||
"""Set the nwItemLayout for a specific file.
|
||||
"""
|
||||
tItem = self.__getitem__(tHandle)
|
||||
if tItem is None:
|
||||
return False
|
||||
if tItem.itemType != nwItemType.FILE:
|
||||
logger.error("Item '%s' is not a file" % tHandle)
|
||||
return False
|
||||
if not isinstance(itemLayout, nwItemLayout):
|
||||
return False
|
||||
|
||||
tItem.setLayout(itemLayout)
|
||||
|
||||
return True
|
||||
|
||||
##
|
||||
# Getters
|
||||
##
|
||||
|
||||
+1
-1
@@ -192,7 +192,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
nHandle = pHandle
|
||||
pHandle = pItem.parHandle
|
||||
|
||||
# If we again has no home, give up
|
||||
# If we again have no home, give up
|
||||
if pHandle is None:
|
||||
self.makeAlert(
|
||||
"Did not find anywhere to add the file or folder!", nwAlert.ERROR
|
||||
|
||||
@@ -324,6 +324,7 @@ class ProjWizardCustomPage(QWizardPage):
|
||||
|
||||
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)
|
||||
|
||||
+1
-4
@@ -281,10 +281,7 @@ class GuiMain(QMainWindow):
|
||||
if projData is None:
|
||||
return False
|
||||
|
||||
projPath = None
|
||||
if "projPath" in projData:
|
||||
projPath = projData["projPath"]
|
||||
|
||||
projPath = projData.get("projPath", None)
|
||||
if projPath is None or projData is None:
|
||||
logger.error("No projData or projPath set")
|
||||
return False
|
||||
|
||||
Reference in New Issue
Block a user