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