Convert folder to document or note (#1128)
This commit is contained in:
+65
-17
@@ -537,7 +537,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
if pHandle is not None and pHandle in self._treeMap:
|
if pHandle is not None and pHandle in self._treeMap:
|
||||||
self._treeMap[pHandle].setExpanded(True)
|
self._treeMap[pHandle].setExpanded(True)
|
||||||
|
|
||||||
self._alertTreeChange(tHandle=tHandle, flush=True)
|
self._alertTreeChange(tHandle, flush=True)
|
||||||
self.clearSelection()
|
self.clearSelection()
|
||||||
trItem.setSelected(True)
|
trItem.setSelected(True)
|
||||||
|
|
||||||
@@ -577,7 +577,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
pItem.insertChild(nIndex, cItem)
|
pItem.insertChild(nIndex, cItem)
|
||||||
self._recordLastMove(cItem, pItem, tIndex)
|
self._recordLastMove(cItem, pItem, tIndex)
|
||||||
|
|
||||||
self._alertTreeChange(tHandle=tHandle, flush=True)
|
self._alertTreeChange(tHandle, flush=True)
|
||||||
self.clearSelection()
|
self.clearSelection()
|
||||||
trItem.setSelected(True)
|
trItem.setSelected(True)
|
||||||
trItem.setExpanded(isExp)
|
trItem.setExpanded(isExp)
|
||||||
@@ -595,7 +595,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
if dlgOk:
|
if dlgOk:
|
||||||
tItem.setName(newLabel)
|
tItem.setName(newLabel)
|
||||||
self.setTreeItemValues(tHandle)
|
self.setTreeItemValues(tHandle)
|
||||||
self._alertTreeChange(tHandle=tHandle, flush=False)
|
self._alertTreeChange(tHandle, flush=False)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -665,7 +665,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
self.deleteItem(tHandle, alreadyAsked=True, bulkAction=True)
|
self.deleteItem(tHandle, alreadyAsked=True, bulkAction=True)
|
||||||
|
|
||||||
if nTrash > 0:
|
if nTrash > 0:
|
||||||
self._alertTreeChange(tHandle=trashHandle, flush=True)
|
self._alertTreeChange(trashHandle, flush=True)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -707,7 +707,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
if trItemS.childCount() == 0:
|
if trItemS.childCount() == 0:
|
||||||
self.takeTopLevelItem(tIndex)
|
self.takeTopLevelItem(tIndex)
|
||||||
self._deleteTreeItem(tHandle)
|
self._deleteTreeItem(tHandle)
|
||||||
self._alertTreeChange(tHandle=tHandle, flush=True)
|
self._alertTreeChange(tHandle, flush=True)
|
||||||
else:
|
else:
|
||||||
self.mainGui.makeAlert(self.tr(
|
self.mainGui.makeAlert(self.tr(
|
||||||
"Cannot delete root folder. It is not empty. "
|
"Cannot delete root folder. It is not empty. "
|
||||||
@@ -723,7 +723,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
tIndex = trItemP.indexOfChild(trItemS)
|
tIndex = trItemP.indexOfChild(trItemS)
|
||||||
trItemP.takeChild(tIndex)
|
trItemP.takeChild(tIndex)
|
||||||
self._deleteTreeItem(tHandle)
|
self._deleteTreeItem(tHandle)
|
||||||
self._alertTreeChange(tHandle=tHandle, flush=autoFlush)
|
self._alertTreeChange(tHandle, flush=autoFlush)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# A populated FOLDER or a FILE requires confirmtation
|
# A populated FOLDER or a FILE requires confirmtation
|
||||||
@@ -759,7 +759,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
self.mainGui.closeDocument()
|
self.mainGui.closeDocument()
|
||||||
self._deleteTreeItem(dHandle)
|
self._deleteTreeItem(dHandle)
|
||||||
|
|
||||||
self._alertTreeChange(tHandle=tHandle, flush=autoFlush)
|
self._alertTreeChange(tHandle, flush=autoFlush)
|
||||||
self.projView.wordCountsChanged.emit()
|
self.projView.wordCountsChanged.emit()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@@ -778,7 +778,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
trItemT.addChild(trItemC)
|
trItemT.addChild(trItemC)
|
||||||
self._postItemMove(tHandle, wCount)
|
self._postItemMove(tHandle, wCount)
|
||||||
self._recordLastMove(trItemS, trItemP, tIndex)
|
self._recordLastMove(trItemS, trItemP, tIndex)
|
||||||
self._alertTreeChange(tHandle=tHandle, flush=autoFlush)
|
self._alertTreeChange(tHandle, flush=autoFlush)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -904,7 +904,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
dstItem.insertChild(dstIndex, movItem)
|
dstItem.insertChild(dstIndex, movItem)
|
||||||
|
|
||||||
self._postItemMove(sHandle, wCount)
|
self._postItemMove(sHandle, wCount)
|
||||||
self._alertTreeChange(tHandle=sHandle, flush=True)
|
self._alertTreeChange(sHandle, flush=True)
|
||||||
|
|
||||||
self.clearSelection()
|
self.clearSelection()
|
||||||
movItem.setSelected(True)
|
movItem.setSelected(True)
|
||||||
@@ -1077,6 +1077,20 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
),
|
),
|
||||||
lambda: self._changeItemLayout(tHandle, nwItemLayout.NOTE)
|
lambda: self._changeItemLayout(tHandle, nwItemLayout.NOTE)
|
||||||
)
|
)
|
||||||
|
elif isFolder:
|
||||||
|
if tItem.documentAllowed():
|
||||||
|
ctxMenu.addAction(
|
||||||
|
self.tr("Convert to {0}").format(
|
||||||
|
trConst(nwLabels.LAYOUT_NAME[nwItemLayout.DOCUMENT])
|
||||||
|
),
|
||||||
|
lambda: self._covertFolderToFile(tHandle, nwItemLayout.DOCUMENT)
|
||||||
|
)
|
||||||
|
ctxMenu.addAction(
|
||||||
|
self.tr("Convert to {0}").format(
|
||||||
|
trConst(nwLabels.LAYOUT_NAME[nwItemLayout.NOTE])
|
||||||
|
),
|
||||||
|
lambda: self._covertFolderToFile(tHandle, nwItemLayout.NOTE)
|
||||||
|
)
|
||||||
|
|
||||||
ctxMenu.addSeparator()
|
ctxMenu.addSeparator()
|
||||||
|
|
||||||
@@ -1154,7 +1168,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
QTreeWidget.dropEvent(self, theEvent)
|
QTreeWidget.dropEvent(self, theEvent)
|
||||||
self._postItemMove(sHandle, wCount)
|
self._postItemMove(sHandle, wCount)
|
||||||
self._recordLastMove(sItem, pItem, pIndex)
|
self._recordLastMove(sItem, pItem, pIndex)
|
||||||
self._alertTreeChange(tHandle=sHandle, flush=True)
|
self._alertTreeChange(sHandle, flush=True)
|
||||||
sItem.setExpanded(isExpanded)
|
sItem.setExpanded(isExpanded)
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -1236,6 +1250,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
if tItem is not None:
|
if tItem is not None:
|
||||||
tItem.setExported(not tItem.isExported)
|
tItem.setExported(not tItem.isExported)
|
||||||
self.setTreeItemValues(tItem.itemHandle)
|
self.setTreeItemValues(tItem.itemHandle)
|
||||||
|
self._alertTreeChange(tHandle, flush=False)
|
||||||
return
|
return
|
||||||
|
|
||||||
def _changeItemStatus(self, tHandle, tStatus):
|
def _changeItemStatus(self, tHandle, tStatus):
|
||||||
@@ -1245,6 +1260,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
if tItem is not None:
|
if tItem is not None:
|
||||||
tItem.setStatus(tStatus)
|
tItem.setStatus(tStatus)
|
||||||
self.setTreeItemValues(tItem.itemHandle)
|
self.setTreeItemValues(tItem.itemHandle)
|
||||||
|
self._alertTreeChange(tHandle, flush=False)
|
||||||
return
|
return
|
||||||
|
|
||||||
def _changeItemImport(self, tHandle, tImport):
|
def _changeItemImport(self, tHandle, tImport):
|
||||||
@@ -1254,6 +1270,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
if tItem is not None:
|
if tItem is not None:
|
||||||
tItem.setImport(tImport)
|
tItem.setImport(tImport)
|
||||||
self.setTreeItemValues(tItem.itemHandle)
|
self.setTreeItemValues(tItem.itemHandle)
|
||||||
|
self._alertTreeChange(tHandle, flush=False)
|
||||||
return
|
return
|
||||||
|
|
||||||
def _changeItemLayout(self, tHandle, itemLayout):
|
def _changeItemLayout(self, tHandle, itemLayout):
|
||||||
@@ -1263,10 +1280,38 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
if tItem is not None:
|
if tItem is not None:
|
||||||
if itemLayout == nwItemLayout.DOCUMENT and tItem.documentAllowed():
|
if itemLayout == nwItemLayout.DOCUMENT and tItem.documentAllowed():
|
||||||
tItem.setLayout(nwItemLayout.DOCUMENT)
|
tItem.setLayout(nwItemLayout.DOCUMENT)
|
||||||
self.setTreeItemValues(tItem.itemHandle)
|
self.setTreeItemValues(tHandle)
|
||||||
|
self._alertTreeChange(tHandle, flush=False)
|
||||||
elif itemLayout == nwItemLayout.NOTE:
|
elif itemLayout == nwItemLayout.NOTE:
|
||||||
tItem.setLayout(nwItemLayout.NOTE)
|
tItem.setLayout(nwItemLayout.NOTE)
|
||||||
self.setTreeItemValues(tItem.itemHandle)
|
self.setTreeItemValues(tHandle)
|
||||||
|
self._alertTreeChange(tHandle, flush=False)
|
||||||
|
return
|
||||||
|
|
||||||
|
def _covertFolderToFile(self, tHandle, itemLayout):
|
||||||
|
"""Convert a folder to a note or document.
|
||||||
|
"""
|
||||||
|
tItem = self.theProject.tree[tHandle]
|
||||||
|
if tItem is not None and tItem.isFolderType():
|
||||||
|
msgYes = self.mainGui.askQuestion(
|
||||||
|
self.tr("Convert Folder"),
|
||||||
|
self.tr(
|
||||||
|
"Do you want to convert the folder to a {0}? "
|
||||||
|
"This action cannot be reversed."
|
||||||
|
).format(trConst(nwLabels.LAYOUT_NAME[itemLayout]))
|
||||||
|
)
|
||||||
|
if msgYes and itemLayout == nwItemLayout.DOCUMENT and tItem.documentAllowed():
|
||||||
|
tItem.setType(nwItemType.FILE)
|
||||||
|
tItem.setLayout(nwItemLayout.DOCUMENT)
|
||||||
|
self.setTreeItemValues(tHandle)
|
||||||
|
self._alertTreeChange(tHandle, flush=False)
|
||||||
|
elif msgYes and itemLayout == nwItemLayout.NOTE:
|
||||||
|
tItem.setType(nwItemType.FILE)
|
||||||
|
tItem.setLayout(nwItemLayout.NOTE)
|
||||||
|
self.setTreeItemValues(tHandle)
|
||||||
|
self._alertTreeChange(tHandle, flush=False)
|
||||||
|
else:
|
||||||
|
logger.info("Folder conversion cancelled")
|
||||||
return
|
return
|
||||||
|
|
||||||
def _scanChildren(self, theList, tItem, tIndex):
|
def _scanChildren(self, theList, tItem, tIndex):
|
||||||
@@ -1351,25 +1396,28 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
trItem = self._addTreeItem(self.theProject.tree[trashHandle])
|
trItem = self._addTreeItem(self.theProject.tree[trashHandle])
|
||||||
if trItem is not None:
|
if trItem is not None:
|
||||||
trItem.setExpanded(True)
|
trItem.setExpanded(True)
|
||||||
self._alertTreeChange(tHandle=trashHandle, flush=True)
|
self._alertTreeChange(trashHandle, flush=True)
|
||||||
|
|
||||||
return trItem
|
return trItem
|
||||||
|
|
||||||
def _alertTreeChange(self, tHandle=None, flush=True):
|
def _alertTreeChange(self, tHandle, flush=False):
|
||||||
"""Update information on tree change state, and emit necessary
|
"""Update information on tree change state, and emit necessary
|
||||||
signals.
|
signals. A flush is only needed if an item is moved, created or
|
||||||
|
deleted.
|
||||||
"""
|
"""
|
||||||
self._timeChanged = time()
|
self._timeChanged = time()
|
||||||
self.theProject.setProjectChanged(True)
|
self.theProject.setProjectChanged(True)
|
||||||
if flush:
|
if flush:
|
||||||
self.saveTreeOrder()
|
self.saveTreeOrder()
|
||||||
|
|
||||||
|
if tHandle is None:
|
||||||
|
return
|
||||||
|
|
||||||
tItem = self.theProject.tree[tHandle]
|
tItem = self.theProject.tree[tHandle]
|
||||||
if tItem is None:
|
if tItem is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
itemType = tItem.itemType
|
if tItem.isRootType():
|
||||||
if itemType == nwItemType.ROOT:
|
|
||||||
self.projView.rootFolderChanged.emit(tHandle)
|
self.projView.rootFolderChanged.emit(tHandle)
|
||||||
|
|
||||||
self.projView.treeItemChanged.emit(tHandle)
|
self.projView.treeItemChanged.emit(tHandle)
|
||||||
|
|||||||
@@ -458,7 +458,7 @@ def testGuiProjTree_DeleteItems(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockR
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.gui
|
@pytest.mark.gui
|
||||||
def testGuiProjTree_ContextMenu(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockRnd):
|
def testGuiProjTree_ContextMenu(qtbot, monkeypatch, nwGUI, fncDir, mockRnd):
|
||||||
"""Test the building of the project tree context menu. All this does
|
"""Test the building of the project tree context menu. All this does
|
||||||
is test that the menu builds. It doesn't open the actual menu,
|
is test that the menu builds. It doesn't open the actual menu,
|
||||||
"""
|
"""
|
||||||
@@ -470,6 +470,8 @@ def testGuiProjTree_ContextMenu(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockR
|
|||||||
monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))
|
monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))
|
||||||
monkeypatch.setattr(QMenu, "exec_", lambda *a: None)
|
monkeypatch.setattr(QMenu, "exec_", lambda *a: None)
|
||||||
|
|
||||||
|
nwTree = nwGUI.projView
|
||||||
|
|
||||||
# Create a project
|
# Create a project
|
||||||
prjDir = os.path.join(fncDir, "project")
|
prjDir = os.path.join(fncDir, "project")
|
||||||
buildTestProject(nwGUI, prjDir)
|
buildTestProject(nwGUI, prjDir)
|
||||||
@@ -544,6 +546,38 @@ def testGuiProjTree_ContextMenu(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockR
|
|||||||
projTree._changeItemLayout(hNovelNote, nwItemLayout.NOTE)
|
projTree._changeItemLayout(hNovelNote, nwItemLayout.NOTE)
|
||||||
assert nwItem.itemLayout == nwItemLayout.NOTE
|
assert nwItem.itemLayout == nwItemLayout.NOTE
|
||||||
|
|
||||||
|
# Convert Folders to Documents
|
||||||
|
# ============================
|
||||||
|
|
||||||
|
hNewFolderOne = "0000000000013"
|
||||||
|
hNewFolderTwo = "0000000000015"
|
||||||
|
|
||||||
|
nwTree.setSelectedHandle(hNovelNote)
|
||||||
|
assert nwTree.projTree.newTreeItem(nwItemType.FOLDER) is True
|
||||||
|
nwTree.setSelectedHandle(hNewFolderOne)
|
||||||
|
assert nwTree.projTree.newTreeItem(nwItemType.FILE) is True
|
||||||
|
|
||||||
|
nwTree.setSelectedHandle(hNovelNote)
|
||||||
|
assert nwTree.projTree.newTreeItem(nwItemType.FOLDER) is True
|
||||||
|
nwTree.setSelectedHandle(hNewFolderTwo)
|
||||||
|
assert nwTree.projTree.newTreeItem(nwItemType.FILE, isNote=True) is True
|
||||||
|
|
||||||
|
# Click no on the dialog
|
||||||
|
with monkeypatch.context() as mp:
|
||||||
|
mp.setattr(QMessageBox, "question", lambda *a: QMessageBox.No)
|
||||||
|
projTree._covertFolderToFile(hNewFolderOne, nwItemLayout.DOCUMENT)
|
||||||
|
assert nwGUI.theProject.tree[hNewFolderOne].isFolderType()
|
||||||
|
|
||||||
|
# Convert the first folder to a document
|
||||||
|
projTree._covertFolderToFile(hNewFolderOne, nwItemLayout.DOCUMENT)
|
||||||
|
assert nwGUI.theProject.tree[hNewFolderOne].isFileType()
|
||||||
|
assert nwGUI.theProject.tree[hNewFolderOne].isDocumentLayout()
|
||||||
|
|
||||||
|
# Convert the second folder to a note
|
||||||
|
projTree._covertFolderToFile(hNewFolderTwo, nwItemLayout.NOTE)
|
||||||
|
assert nwGUI.theProject.tree[hNewFolderTwo].isFileType()
|
||||||
|
assert nwGUI.theProject.tree[hNewFolderTwo].isNoteLayout()
|
||||||
|
|
||||||
# qtbot.stop()
|
# qtbot.stop()
|
||||||
|
|
||||||
# END Test testGuiProjTree_ContextMenu
|
# END Test testGuiProjTree_ContextMenu
|
||||||
|
|||||||
Reference in New Issue
Block a user