Merge branch 'main' into primary_count
This commit is contained in:
@@ -383,10 +383,12 @@ class ProjectBuilder:
|
||||
"""Build or copy a project from a data dictionary."""
|
||||
if isinstance(data, dict):
|
||||
path = data.get("path", None) or None
|
||||
if author := data.get("author"):
|
||||
CONFIG.setLastAuthor(author)
|
||||
if isinstance(path, str | Path):
|
||||
self._path = Path(path).resolve()
|
||||
if data.get("sample"):
|
||||
return self._extractSampleProject(self._path)
|
||||
return self._extractSampleProject(self._path, data)
|
||||
elif data.get("template"):
|
||||
return self._copyProject(self._path, data)
|
||||
else:
|
||||
@@ -416,20 +418,21 @@ class ProjectBuilder:
|
||||
|
||||
self._path = project.storage.storagePath
|
||||
|
||||
lblNewProject = self.tr("New Project")
|
||||
lblTitlePage = self.tr("Title Page")
|
||||
trName = self.tr("New Project")
|
||||
trAuthor = self.tr("Author Name")
|
||||
trTitlePage = self.tr("Title Page")
|
||||
|
||||
# Settings
|
||||
project.data.setUuid(None)
|
||||
project.data.setName(data.get("name", lblNewProject))
|
||||
project.data.setAuthor(data.get("author", ""))
|
||||
project.data.setName(data.get("name", trName))
|
||||
project.data.setAuthor(data.get("author", trAuthor))
|
||||
project.data.setLanguage(CONFIG.guiLocale)
|
||||
project.setDefaultStatusImport()
|
||||
project.session.startSession()
|
||||
|
||||
# Add Root Folders
|
||||
hNovelRoot = project.newRoot(nwItemClass.NOVEL)
|
||||
hTitlePage = project.newFile(lblTitlePage, hNovelRoot)
|
||||
hTitlePage = project.newFile(trTitlePage, hNovelRoot)
|
||||
|
||||
# Generate Title Page
|
||||
aDoc = project.storage.getDocument(hTitlePage)
|
||||
@@ -446,25 +449,21 @@ class ProjectBuilder:
|
||||
"\n"
|
||||
">> {count}: [field:{field}] <<\n"
|
||||
).format(
|
||||
author=project.data.author or "None",
|
||||
address=self.tr("Address"),
|
||||
title=project.data.name or "None",
|
||||
author=project.data.author or trAuthor,
|
||||
address=self.tr("Address Line"),
|
||||
title=project.data.name or trName,
|
||||
by=self.tr("By"),
|
||||
count=self.tr("Word Count"),
|
||||
field=nwStats.WORDS_TEXT,
|
||||
))
|
||||
|
||||
# Create a project structure based on selected root folders
|
||||
# and a number of chapters and scenes selected in the
|
||||
# wizard's custom page.
|
||||
|
||||
# Create chapters and scenes
|
||||
numChapters = data.get("chapters", 0)
|
||||
numScenes = data.get("scenes", 0)
|
||||
|
||||
chSynop = self.tr("Summary of the chapter.")
|
||||
scSynop = self.tr("Summary of the scene.")
|
||||
bfNote = self.tr("A short description.")
|
||||
trChSynop = self.tr("Summary of the chapter.")
|
||||
trScSynop = self.tr("Summary of the scene.")
|
||||
trNoteDesc = self.tr("A short description.")
|
||||
|
||||
# Create chapters
|
||||
if numChapters > 0:
|
||||
@@ -472,7 +471,7 @@ class ProjectBuilder:
|
||||
chTitle = self.tr("Chapter {0}").format(f"{ch+1:d}")
|
||||
cHandle = project.newFile(chTitle, hNovelRoot)
|
||||
aDoc = project.storage.getDocument(cHandle)
|
||||
aDoc.writeDocument(f"## {chTitle}\n\n%Synopsis: {chSynop}\n\n")
|
||||
aDoc.writeDocument(f"## {chTitle}\n\n%Synopsis: {trChSynop}\n\n")
|
||||
|
||||
# Create chapter scenes
|
||||
if numScenes > 0 and cHandle:
|
||||
@@ -480,7 +479,7 @@ class ProjectBuilder:
|
||||
scTitle = self.tr("Scene {0}").format(f"{ch+1:d}.{sc+1:d}")
|
||||
sHandle = project.newFile(scTitle, cHandle)
|
||||
aDoc = project.storage.getDocument(sHandle)
|
||||
aDoc.writeDocument(f"### {scTitle}\n\n%Synopsis: {scSynop}\n\n")
|
||||
aDoc.writeDocument(f"### {scTitle}\n\n%Synopsis: {trScSynop}\n\n")
|
||||
|
||||
# Create scenes (no chapters)
|
||||
elif numScenes > 0:
|
||||
@@ -488,7 +487,7 @@ class ProjectBuilder:
|
||||
scTitle = self.tr("Scene {0}").format(f"{sc+1:d}")
|
||||
sHandle = project.newFile(scTitle, hNovelRoot)
|
||||
aDoc = project.storage.getDocument(sHandle)
|
||||
aDoc.writeDocument(f"### {scTitle}\n\n%Synopsis: {scSynop}\n\n")
|
||||
aDoc.writeDocument(f"### {scTitle}\n\n%Synopsis: {trScSynop}\n\n")
|
||||
|
||||
# Create notes folders
|
||||
noteTitles = {
|
||||
@@ -508,7 +507,7 @@ class ProjectBuilder:
|
||||
aDoc.writeDocument(
|
||||
f"# {noteTitles[newRoot]}\n\n"
|
||||
f"@tag: {ntTag}\n\n"
|
||||
f"%Short: {bfNote}\n\n"
|
||||
f"%Short: {trNoteDesc}\n\n"
|
||||
)
|
||||
|
||||
# Also add the archive and trash folders
|
||||
@@ -563,23 +562,11 @@ class ProjectBuilder:
|
||||
return False
|
||||
|
||||
# Open the copied project and update settings
|
||||
project = NWProject()
|
||||
project.openProject(dstPath)
|
||||
project.data.setUuid("") # Creates a fresh uuid
|
||||
project.data.setName(data.get("name", "None"))
|
||||
project.data.setAuthor(data.get("author", ""))
|
||||
project.data.setSpellCheck(True)
|
||||
project.data.setSpellLang(None)
|
||||
project.data.setDoBackup(True)
|
||||
project.data.setSaveCount(0)
|
||||
project.data.setAutoCount(0)
|
||||
project.data.setEditTime(0)
|
||||
project.saveProject()
|
||||
project.closeProject()
|
||||
self._resetProject(dstPath, data)
|
||||
|
||||
return True
|
||||
|
||||
def _extractSampleProject(self, path: Path) -> bool:
|
||||
def _extractSampleProject(self, path: Path, data: dict) -> bool:
|
||||
"""Make a copy of the sample project by extracting the
|
||||
sample.zip file to the new path.
|
||||
"""
|
||||
@@ -593,6 +580,7 @@ class ProjectBuilder:
|
||||
if (sample := CONFIG.assetPath("sample.zip")).is_file():
|
||||
try:
|
||||
shutil.unpack_archive(sample, path)
|
||||
self._resetProject(path, data)
|
||||
except Exception as exc:
|
||||
SHARED.error(self.tr("Failed to create a new example project."), exc=exc)
|
||||
return False
|
||||
@@ -605,3 +593,22 @@ class ProjectBuilder:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def _resetProject(self, path: Path, data: dict) -> None:
|
||||
"""Open a project and reset/update its settings."""
|
||||
project = NWProject()
|
||||
project.openProject(path)
|
||||
project.data.setUuid("") # Creates a fresh uuid
|
||||
if name := data.get("name", ""):
|
||||
project.data.setName(name)
|
||||
if author := data.get("author", ""):
|
||||
project.data.setAuthor(author)
|
||||
project.data.setSpellCheck(True)
|
||||
project.data.setSpellLang(None)
|
||||
project.data.setDoBackup(True)
|
||||
project.data.setSaveCount(0)
|
||||
project.data.setAutoCount(0)
|
||||
project.data.setEditTime(0)
|
||||
project.saveProject()
|
||||
project.closeProject()
|
||||
return
|
||||
|
||||
@@ -45,16 +45,18 @@ logger = logging.getLogger(__name__)
|
||||
INV_ROOT = "invisibleRoot"
|
||||
C_FACTOR = 0x0100
|
||||
|
||||
C_LABEL_TEXT = 0x0000 | Qt.ItemDataRole.DisplayRole
|
||||
C_LABEL_ICON = 0x0000 | Qt.ItemDataRole.DecorationRole
|
||||
C_LABEL_FONT = 0x0000 | Qt.ItemDataRole.FontRole
|
||||
C_COUNT_TEXT = 0x0100 | Qt.ItemDataRole.DisplayRole
|
||||
C_COUNT_ICON = 0x0100 | Qt.ItemDataRole.DecorationRole
|
||||
C_COUNT_ALIGN = 0x0100 | Qt.ItemDataRole.TextAlignmentRole
|
||||
C_ACTIVE_ICON = 0x0200 | Qt.ItemDataRole.DecorationRole
|
||||
C_ACTIVE_TIP = 0x0200 | Qt.ItemDataRole.ToolTipRole
|
||||
C_STATUS_ICON = 0x0300 | Qt.ItemDataRole.DecorationRole
|
||||
C_STATUS_TIP = 0x0300 | Qt.ItemDataRole.ToolTipRole
|
||||
C_LABEL_TEXT = 0x0000 | Qt.ItemDataRole.DisplayRole
|
||||
C_LABEL_ICON = 0x0000 | Qt.ItemDataRole.DecorationRole
|
||||
C_LABEL_FONT = 0x0000 | Qt.ItemDataRole.FontRole
|
||||
C_COUNT_TEXT = 0x0100 | Qt.ItemDataRole.DisplayRole
|
||||
C_COUNT_ICON = 0x0100 | Qt.ItemDataRole.DecorationRole
|
||||
C_COUNT_ALIGN = 0x0100 | Qt.ItemDataRole.TextAlignmentRole
|
||||
C_ACTIVE_ICON = 0x0200 | Qt.ItemDataRole.DecorationRole
|
||||
C_ACTIVE_TIP = 0x0200 | Qt.ItemDataRole.ToolTipRole
|
||||
C_ACTIVE_ACCESS = 0x0200 | Qt.ItemDataRole.AccessibleTextRole
|
||||
C_STATUS_ICON = 0x0300 | Qt.ItemDataRole.DecorationRole
|
||||
C_STATUS_TIP = 0x0300 | Qt.ItemDataRole.ToolTipRole
|
||||
C_STATUS_ACCESS = 0x0300 | Qt.ItemDataRole.AccessibleTextRole
|
||||
|
||||
NODE_FLAGS = Qt.ItemFlag.ItemIsEnabled
|
||||
NODE_FLAGS |= Qt.ItemFlag.ItemIsSelectable
|
||||
@@ -150,13 +152,15 @@ class ProjectNode:
|
||||
|
||||
# Active
|
||||
aText, aIcon = self._item.getActiveStatus()
|
||||
self._cache[C_ACTIVE_TIP] = aText
|
||||
self._cache[C_ACTIVE_ICON] = aIcon
|
||||
self._cache[C_ACTIVE_TIP] = aText
|
||||
self._cache[C_ACTIVE_ACCESS] = aText
|
||||
|
||||
# Status
|
||||
sText, sIcon = self._item.getImportStatus()
|
||||
self._cache[C_STATUS_TIP] = sText
|
||||
self._cache[C_STATUS_ICON] = sIcon
|
||||
self._cache[C_STATUS_TIP] = sText
|
||||
self._cache[C_STATUS_ACCESS] = sText
|
||||
|
||||
return
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ R_TEXT = Qt.ItemDataRole.DisplayRole
|
||||
R_ICON = Qt.ItemDataRole.DecorationRole
|
||||
R_ALIGN = Qt.ItemDataRole.TextAlignmentRole
|
||||
R_TIP = Qt.ItemDataRole.ToolTipRole
|
||||
R_ACCESS = Qt.ItemDataRole.AccessibleTextRole
|
||||
R_HANDLE = 0xff01
|
||||
R_KEY = 0xff02
|
||||
|
||||
@@ -217,6 +218,7 @@ class NovelModel(QAbstractTableModel):
|
||||
text = ", ".join(refs)
|
||||
data[C_FACTOR*2 | R_TEXT] = text
|
||||
data[C_FACTOR*2 | R_TIP] = f"<b>{self._extraLabel}:</b> {text}"
|
||||
data[C_FACTOR*2 | R_ACCESS] = f"{self._extraLabel}: {text}"
|
||||
data[C_FACTOR*3 | R_ICON] = self._more
|
||||
data[R_HANDLE] = handle
|
||||
data[R_KEY] = key
|
||||
|
||||
@@ -483,14 +483,14 @@ class NWProject:
|
||||
|
||||
def setDefaultStatusImport(self) -> None:
|
||||
"""Set the default status and importance values."""
|
||||
self._data.itemStatus.add(None, self.tr("New"), (100, 100, 100), "SQUARE", 0)
|
||||
self._data.itemStatus.add(None, self.tr("Note"), (200, 50, 0), "SQUARE", 0)
|
||||
self._data.itemStatus.add(None, self.tr("Draft"), (200, 150, 0), "SQUARE", 0)
|
||||
self._data.itemStatus.add(None, self.tr("Finished"), (50, 200, 0), "SQUARE", 0)
|
||||
self._data.itemImport.add(None, self.tr("New"), (100, 100, 100), "SQUARE", 0)
|
||||
self._data.itemImport.add(None, self.tr("Minor"), (200, 50, 0), "SQUARE", 0)
|
||||
self._data.itemImport.add(None, self.tr("Major"), (200, 150, 0), "SQUARE", 0)
|
||||
self._data.itemImport.add(None, self.tr("Main"), (50, 200, 0), "SQUARE", 0)
|
||||
self._data.itemStatus.add(None, self.tr("New"), (120, 120, 120), "STAR", 0)
|
||||
self._data.itemStatus.add(None, self.tr("Note"), (205, 171, 143), "TRIANGLE", 0)
|
||||
self._data.itemStatus.add(None, self.tr("Draft"), (143, 240, 164), "CIRCLE_T", 0)
|
||||
self._data.itemStatus.add(None, self.tr("Finished"), (249, 240, 107), "STAR", 0)
|
||||
self._data.itemImport.add(None, self.tr("New"), (120, 120, 120), "SQUARE", 0)
|
||||
self._data.itemImport.add(None, self.tr("Minor"), (220, 138, 221), "BLOCK_2", 0)
|
||||
self._data.itemImport.add(None, self.tr("Major"), (220, 138, 221), "BLOCK_3", 0)
|
||||
self._data.itemImport.add(None, self.tr("Main"), (220, 138, 221), "BLOCK_4", 0)
|
||||
return
|
||||
|
||||
def setProjectLang(self, language: str | None) -> None:
|
||||
|
||||
Reference in New Issue
Block a user