Re-enable project tree context menu and clean up split and merge

This commit is contained in:
Veronica Berglyd Olsen
2024-11-20 16:42:08 +01:00
parent 3f41e62e21
commit 072be78991
4 changed files with 539 additions and 604 deletions
+88 -100
View File
@@ -56,10 +56,17 @@ class DocMerger:
def __init__(self, project: NWProject) -> None:
self._project = project
self._error = ""
self._targetDoc = None
self._targetText = []
self._target = None
self._text = []
return
@property
def targetHandle(self) -> str | None:
"""Get the handle of the target document."""
if self._target:
return self._target.itemHandle
return None
##
# Methods
##
@@ -72,63 +79,56 @@ class DocMerger:
"""Set the target document for the merging. Calling this
function resets the class.
"""
self._targetDoc = tHandle
self._targetText = []
self._target = self._project.tree[tHandle]
self._text = []
return
def newTargetDoc(self, srcHandle: str, docLabel: str) -> str | None:
def newTargetDoc(self, sHandle: str, label: str) -> None:
"""Create a brand new target document based on a source handle
and a new doc label. Calling this function resets the class.
"""
srcItem = self._project.tree[srcHandle]
if srcItem is None or srcItem.itemParent is None:
return None
sItem = self._project.tree[sHandle]
if sItem and sItem.itemParent:
tHandle = self._project.newFile(label, sItem.itemParent)
if nwItem := self._project.tree[tHandle]:
nwItem.setLayout(sItem.itemLayout)
nwItem.setStatus(sItem.itemStatus)
nwItem.setImport(sItem.itemImport)
nwItem.notifyToRefresh()
self._target = nwItem
self._text = []
return
newHandle = self._project.newFile(docLabel, srcItem.itemParent)
newItem = self._project.tree[newHandle]
if isinstance(newItem, NWItem):
newItem.setLayout(srcItem.itemLayout)
newItem.setStatus(srcItem.itemStatus)
newItem.setImport(srcItem.itemImport)
self._targetDoc = newHandle
self._targetText = []
return newHandle
def appendText(self, srcHandle: str, addComment: bool, cmtPrefix: str) -> bool:
def appendText(self, sHandle: str, addComment: bool, cmtPrefix: str) -> None:
"""Append text from an existing document to the text buffer."""
srcItem = self._project.tree[srcHandle]
if srcItem is None:
return False
docText = self._project.storage.getDocumentText(srcHandle).rstrip("\n")
if addComment:
docInfo = srcItem.describeMe()
docSt, _ = srcItem.getImportStatus()
cmtLine = f"% {cmtPrefix} {docInfo}: {srcItem.itemName} [{docSt}]\n\n"
docText = cmtLine + docText
self._targetText.append(docText)
return True
if item := self._project.tree[sHandle]:
text = self._project.storage.getDocumentText(sHandle).rstrip("\n")
if addComment:
info = item.describeMe()
status, _ = item.getImportStatus()
text = f"% {cmtPrefix} {info}: {item.itemName} [{status}]\n\n{text}"
self._text.append(text)
return
def writeTargetDoc(self) -> bool:
"""Write the accumulated text into the designated target
document, appending any existing text.
"""
if self._targetDoc is None:
return False
if self._target:
outDoc = self._project.storage.getDocument(self._target.itemHandle)
if text := (outDoc.readDocument() or "").rstrip("\n"):
self._text.insert(0, text)
outDoc = self._project.storage.getDocument(self._targetDoc)
if text := (outDoc.readDocument() or "").rstrip("\n"):
self._targetText.insert(0, text)
status = outDoc.writeDocument("\n\n".join(self._text) + "\n\n")
if not status:
self._error = outDoc.getError()
status = outDoc.writeDocument("\n\n".join(self._targetText) + "\n\n")
if not status:
self._error = outDoc.getError()
self._project.index.reIndexHandle(self._target.itemHandle)
self._target.notifyToRefresh()
return status
return status
return False
class DocSplitter:
@@ -172,23 +172,19 @@ class DocSplitter:
self._inFolder = False
return
def newParentFolder(self, pHandle: str, folderLabel: str) -> str | None:
def newParentFolder(self, pHandle: str, folderLabel: str) -> None:
"""Create a new folder that will be the top level parent item
for the new documents.
"""
if self._srcItem is None:
return None
newHandle = self._project.newFolder(folderLabel, pHandle)
newItem = self._project.tree[newHandle]
if isinstance(newItem, NWItem):
newItem.setStatus(self._srcItem.itemStatus)
newItem.setImport(self._srcItem.itemImport)
self._parHandle = newHandle
self._inFolder = True
return newHandle
if self._srcItem:
nHandle = self._project.newFolder(folderLabel, pHandle)
if nwItem := self._project.tree[nHandle]:
nwItem.setStatus(self._srcItem.itemStatus)
nwItem.setImport(self._srcItem.itemImport)
nwItem.notifyToRefresh()
self._parHandle = nHandle
self._inFolder = True
return
def splitDocument(self, splitData: list, splitText: list[str]) -> None:
"""Loop through the split data record and perform the split job
@@ -202,58 +198,50 @@ class DocSplitter:
self._rawData.insert(0, (chunk, hLevel, hLabel))
return
def writeDocuments(self, docHierarchy: bool) -> Iterable[tuple[bool, str | None, str | None]]:
def writeDocuments(self, docHierarchy: bool) -> Iterable[bool]:
"""An iterator that will write each document in the buffer, and
return its new handle, parent handle, and sibling handle.
"""
if self._srcHandle is None or self._srcItem is None or self._parHandle is None:
return
if self._srcHandle and self._srcItem and self._parHandle:
pHandle = self._parHandle
hHandle = [self._parHandle, None, None, None, None]
pLevel = 0
for docText, hLevel, docLabel in self._rawData:
pHandle = self._parHandle
nHandle = self._parHandle if self._inFolder else self._srcHandle
hHandle = [self._parHandle, None, None, None, None]
hLevel = minmax(hLevel, 1, 4)
if pLevel == 0:
pLevel = hLevel
pLevel = 0
for docText, hLevel, docLabel in self._rawData:
if docHierarchy:
if hLevel == 1:
pHandle = self._parHandle
elif hLevel == 2:
pHandle = hHandle[1] or hHandle[0]
elif hLevel == 3:
pHandle = hHandle[2] or hHandle[1] or hHandle[0]
elif hLevel == 4:
pHandle = hHandle[3] or hHandle[2] or hHandle[1] or hHandle[0]
hLevel = minmax(hLevel, 1, 4)
if pLevel == 0:
pLevel = hLevel
if (
(dHandle := self._project.newFile(docLabel, pHandle))
and (nwItem := self._project.tree[dHandle])
):
hHandle[hLevel] = dHandle
nwItem.setStatus(self._srcItem.itemStatus)
nwItem.setImport(self._srcItem.itemImport)
if docHierarchy:
if hLevel == 1:
pHandle = self._parHandle
elif hLevel == 2:
pHandle = hHandle[1] or hHandle[0]
elif hLevel == 3:
pHandle = hHandle[2] or hHandle[1] or hHandle[0]
elif hLevel == 4:
pHandle = hHandle[3] or hHandle[2] or hHandle[1] or hHandle[0]
outDoc = self._project.storage.getDocument(dHandle)
status = outDoc.writeDocument("\n".join(docText))
if not status:
self._error = outDoc.getError()
if hLevel < pLevel:
nHandle = hHandle[hLevel] or hHandle[0]
elif hLevel > pLevel:
nHandle = pHandle
self._project.index.reIndexHandle(dHandle)
nwItem.notifyToRefresh()
dHandle = self._project.newFile(docLabel, pHandle)
hHandle[hLevel] = dHandle
newItem = self._project.tree[dHandle]
if isinstance(newItem, NWItem):
newItem.setStatus(self._srcItem.itemStatus)
newItem.setImport(self._srcItem.itemImport)
outDoc = self._project.storage.getDocument(dHandle)
status = outDoc.writeDocument("\n".join(docText))
if not status:
self._error = outDoc.getError()
yield status, dHandle, nHandle
hHandle[hLevel] = dHandle
nHandle = dHandle
pLevel = hLevel
yield status
hHandle[hLevel] = dHandle
pLevel = hLevel
return
+6
View File
@@ -391,6 +391,12 @@ class NWTree:
return tTree
def subTree(self, tHandle: str) -> list[str]:
"""Get the subtree from a given handle."""
if node := self._nodes.get(tHandle):
return [child.item.itemHandle for child in node.allChildren()]
return []
##
# Tree Root Methods
##
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -1321,11 +1321,11 @@ def testGuiProjTree_ContextMenu(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
# Click no on the dialog
with monkeypatch.context() as mp:
mp.setattr(QMessageBox, "result", lambda *a: QMessageBox.StandardButton.No)
ctxMenu._covertFolderToFile(nwItemLayout.DOCUMENT)
ctxMenu._convertFolderToFile(nwItemLayout.DOCUMENT)
assert SHARED.project.tree[hNewFolderOne].isFolderType() # type: ignore
# Convert the first folder to a document
ctxMenu._covertFolderToFile(nwItemLayout.DOCUMENT)
ctxMenu._convertFolderToFile(nwItemLayout.DOCUMENT)
assert SHARED.project.tree[hNewFolderOne].isFileType() # type: ignore
assert SHARED.project.tree[hNewFolderOne].isDocumentLayout() # type: ignore
@@ -1335,7 +1335,7 @@ def testGuiProjTree_ContextMenu(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
ctxMenu.buildSingleSelectMenu(False)
# Convert the second folder to a note
ctxMenu._covertFolderToFile(nwItemLayout.NOTE)
ctxMenu._convertFolderToFile(nwItemLayout.NOTE)
assert SHARED.project.tree[hNewFolderTwo].isFileType() # type: ignore
assert SHARED.project.tree[hNewFolderTwo].isNoteLayout() # type: ignore