Add a context menu option to rename a document from any title within it
This commit is contained in:
@@ -98,6 +98,7 @@ class GuiDocEditor(QPlainTextEdit):
|
|||||||
closeDocumentRequest = pyqtSignal()
|
closeDocumentRequest = pyqtSignal()
|
||||||
toggleFocusModeRequest = pyqtSignal()
|
toggleFocusModeRequest = pyqtSignal()
|
||||||
requestProjectItemSelected = pyqtSignal(str, bool)
|
requestProjectItemSelected = pyqtSignal(str, bool)
|
||||||
|
requestProjectItemRenamed = pyqtSignal(str, str)
|
||||||
|
|
||||||
def __init__(self, mainGui: GuiMain) -> None:
|
def __init__(self, mainGui: GuiMain) -> None:
|
||||||
super().__init__(parent=mainGui)
|
super().__init__(parent=mainGui)
|
||||||
@@ -371,7 +372,7 @@ class GuiDocEditor(QPlainTextEdit):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def loadText(self, tHandle, tLine=None) -> bool:
|
def loadText(self, tHandle: str, tLine=None) -> bool:
|
||||||
"""Load text from a document into the editor. If we have an I/O
|
"""Load text from a document into the editor. If we have an I/O
|
||||||
error, we must handle this and clear the editor so that we don't
|
error, we must handle this and clear the editor so that we don't
|
||||||
risk overwriting the file if it exists. This can for instance
|
risk overwriting the file if it exists. This can for instance
|
||||||
@@ -1071,8 +1072,12 @@ class GuiDocEditor(QPlainTextEdit):
|
|||||||
"""
|
"""
|
||||||
uCursor = self.textCursor()
|
uCursor = self.textCursor()
|
||||||
pCursor = self.cursorForPosition(pos)
|
pCursor = self.cursorForPosition(pos)
|
||||||
|
pBlock = pCursor.block()
|
||||||
|
|
||||||
ctxMenu = QMenu(self)
|
ctxMenu = QMenu(self)
|
||||||
|
if pBlock.userState() == GuiDocHighlighter.BLOCK_TITLE:
|
||||||
|
aLabel = ctxMenu.addAction(self.tr("Set as Document Name"))
|
||||||
|
aLabel.triggered.connect(lambda: self._emitRenameItem(pBlock))
|
||||||
|
|
||||||
# Follow
|
# Follow
|
||||||
status = self._processTag(cursor=pCursor, follow=False)
|
status = self._processTag(cursor=pCursor, follow=False)
|
||||||
@@ -1867,6 +1872,13 @@ class GuiDocEditor(QPlainTextEdit):
|
|||||||
|
|
||||||
return nwTrinary.NEUTRAL
|
return nwTrinary.NEUTRAL
|
||||||
|
|
||||||
|
def _emitRenameItem(self, block: QTextBlock) -> None:
|
||||||
|
"""Emit a signal to request an item be renamed."""
|
||||||
|
if self._docHandle:
|
||||||
|
text = block.text().lstrip("#").lstrip("!").strip()
|
||||||
|
self.requestProjectItemRenamed.emit(self._docHandle, text)
|
||||||
|
return
|
||||||
|
|
||||||
def _openContextFromCursor(self) -> None:
|
def _openContextFromCursor(self) -> None:
|
||||||
"""Open the spell check context menu at the cursor."""
|
"""Open the spell check context menu at the cursor."""
|
||||||
self._openContextMenu(self.cursorRect().center())
|
self._openContextMenu(self.cursorRect().center())
|
||||||
|
|||||||
+17
-17
@@ -190,17 +190,20 @@ class GuiProjectView(QWidget):
|
|||||||
"""Check if the project tree has focus."""
|
"""Check if the project tree has focus."""
|
||||||
return self.projTree.hasFocus()
|
return self.projTree.hasFocus()
|
||||||
|
|
||||||
def renameTreeItem(self, tHandle: str | None = None) -> bool:
|
##
|
||||||
|
# Public Slots
|
||||||
|
##
|
||||||
|
|
||||||
|
@pyqtSlot(str, str)
|
||||||
|
def renameTreeItem(self, tHandle: str | None = None, name: str = "") -> None:
|
||||||
"""External request to rename an item or the currently selected
|
"""External request to rename an item or the currently selected
|
||||||
item. This is triggered by the global menu or keyboard shortcut.
|
item. This is triggered by the global menu or keyboard shortcut.
|
||||||
"""
|
"""
|
||||||
if tHandle is None:
|
if tHandle is None:
|
||||||
tHandle = self.projTree.getSelectedHandle()
|
tHandle = self.projTree.getSelectedHandle()
|
||||||
return self.projTree.renameTreeItem(tHandle) if tHandle else False
|
if tHandle:
|
||||||
|
self.projTree.renameTreeItem(tHandle, name=name)
|
||||||
##
|
return
|
||||||
# Public Slots
|
|
||||||
##
|
|
||||||
|
|
||||||
@pyqtSlot(str, bool)
|
@pyqtSlot(str, bool)
|
||||||
def setSelectedHandle(self, tHandle: str, doScroll: bool = False) -> None:
|
def setSelectedHandle(self, tHandle: str, doScroll: bool = False) -> None:
|
||||||
@@ -766,19 +769,16 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
self.setCurrentItem(tItem.child(0))
|
self.setCurrentItem(tItem.child(0))
|
||||||
return
|
return
|
||||||
|
|
||||||
def renameTreeItem(self, tHandle: str) -> bool:
|
def renameTreeItem(self, tHandle: str, name: str = "") -> None:
|
||||||
"""Open a dialog to edit the label of an item."""
|
"""Open a dialog to edit the label of an item."""
|
||||||
tItem = SHARED.project.tree[tHandle]
|
tItem = SHARED.project.tree[tHandle]
|
||||||
if tItem is None:
|
if tItem:
|
||||||
return False
|
newLabel, dlgOk = GuiEditLabel.getLabel(self, text=name or tItem.itemName)
|
||||||
|
if dlgOk:
|
||||||
newLabel, dlgOk = GuiEditLabel.getLabel(self, text=tItem.itemName)
|
tItem.setName(newLabel)
|
||||||
if dlgOk:
|
self.setTreeItemValues(tHandle)
|
||||||
tItem.setName(newLabel)
|
self._alertTreeChange(tHandle, flush=False)
|
||||||
self.setTreeItemValues(tHandle)
|
return
|
||||||
self._alertTreeChange(tHandle, flush=False)
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def saveTreeOrder(self) -> None:
|
def saveTreeOrder(self) -> None:
|
||||||
"""Build a list of the items in the project tree and send them
|
"""Build a list of the items in the project tree and send them
|
||||||
|
|||||||
@@ -285,6 +285,7 @@ class GuiMain(QMainWindow):
|
|||||||
self.docEditor.closeDocumentRequest.connect(self.closeDocEditor)
|
self.docEditor.closeDocumentRequest.connect(self.closeDocEditor)
|
||||||
self.docEditor.toggleFocusModeRequest.connect(self.toggleFocusMode)
|
self.docEditor.toggleFocusModeRequest.connect(self.toggleFocusMode)
|
||||||
self.docEditor.requestProjectItemSelected.connect(self.projView.setSelectedHandle)
|
self.docEditor.requestProjectItemSelected.connect(self.projView.setSelectedHandle)
|
||||||
|
self.docEditor.requestProjectItemRenamed.connect(self.projView.renameTreeItem)
|
||||||
|
|
||||||
self.docViewer.documentLoaded.connect(self.docViewerPanel.updateHandle)
|
self.docViewer.documentLoaded.connect(self.docViewerPanel.updateHandle)
|
||||||
self.docViewer.loadDocumentTagRequest.connect(self._followTag)
|
self.docViewer.loadDocumentTagRequest.connect(self._followTag)
|
||||||
|
|||||||
@@ -156,12 +156,9 @@ def testGuiProjTree_NewItems(qtbot, caplog, monkeypatch, nwGUI, projPath, mockRn
|
|||||||
# Rename plot folder
|
# Rename plot folder
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setattr(GuiEditLabel, "getLabel", lambda *a, **k: ("Stuff", True))
|
mp.setattr(GuiEditLabel, "getLabel", lambda *a, **k: ("Stuff", True))
|
||||||
projTree.renameTreeItem(C.hPlotRoot) is True
|
projTree.renameTreeItem(C.hPlotRoot)
|
||||||
assert project.tree[C.hPlotRoot].itemName == "Stuff" # type: ignore
|
assert project.tree[C.hPlotRoot].itemName == "Stuff" # type: ignore
|
||||||
|
|
||||||
# Rename invalid folder
|
|
||||||
projTree.renameTreeItem("0000000000000") is False
|
|
||||||
|
|
||||||
# Other Checks
|
# Other Checks
|
||||||
# ============
|
# ============
|
||||||
|
|
||||||
@@ -1095,12 +1092,12 @@ def testGuiProjTree_Other(qtbot, monkeypatch, nwGUI: GuiMain, projPath, mockRnd)
|
|||||||
mp.setattr(GuiEditLabel, "getLabel", lambda *a, **k: ("FooBar", True))
|
mp.setattr(GuiEditLabel, "getLabel", lambda *a, **k: ("FooBar", True))
|
||||||
projTree.clearSelection()
|
projTree.clearSelection()
|
||||||
assert SHARED.project.tree[C.hChapterDoc].itemName == "New Chapter" # type: ignore
|
assert SHARED.project.tree[C.hChapterDoc].itemName == "New Chapter" # type: ignore
|
||||||
assert projView.renameTreeItem(C.hChapterDoc) is True
|
projView.renameTreeItem(C.hChapterDoc)
|
||||||
assert SHARED.project.tree[C.hChapterDoc].itemName == "FooBar" # type: ignore
|
assert SHARED.project.tree[C.hChapterDoc].itemName == "FooBar" # type: ignore
|
||||||
|
|
||||||
projTree.setSelectedHandle(C.hSceneDoc)
|
projTree.setSelectedHandle(C.hSceneDoc)
|
||||||
assert SHARED.project.tree[C.hSceneDoc].itemName == "New Scene" # type: ignore
|
assert SHARED.project.tree[C.hSceneDoc].itemName == "New Scene" # type: ignore
|
||||||
assert projView.renameTreeItem() is True
|
projView.renameTreeItem()
|
||||||
assert SHARED.project.tree[C.hSceneDoc].itemName == "FooBar" # type: ignore
|
assert SHARED.project.tree[C.hSceneDoc].itemName == "FooBar" # type: ignore
|
||||||
|
|
||||||
# Check Crash Resistance
|
# Check Crash Resistance
|
||||||
|
|||||||
Reference in New Issue
Block a user