Clean up document header signals

This commit is contained in:
Veronica Berglyd Olsen
2023-11-07 17:47:59 +01:00
parent a07177c153
commit e236fb30dc
5 changed files with 180 additions and 169 deletions
+2 -2
View File
@@ -77,10 +77,10 @@ Text Search Shortcuts
":kbd:`F3`", "Find the next occurrence of the search word" ":kbd:`F3`", "Find the next occurrence of the search word"
":kbd:`Ctrl+F`", "Open the search bar and search for the selected word, if any is selected" ":kbd:`Ctrl+F`", "Open the search bar and search for the selected word, if any is selected"
":kbd:`Ctrl+G`", "Find next occurrence of search word in current document" ":kbd:`Ctrl+G`", "Find the next occurrence of the search word"
":kbd:`Ctrl+H`", "Open the search tool and populate with the selected word (Mac :kbd:`Cmd+=`)" ":kbd:`Ctrl+H`", "Open the search tool and populate with the selected word (Mac :kbd:`Cmd+=`)"
":kbd:`Ctrl+Shift+1`", "Replace selected occurrence of the search word, and move to the next" ":kbd:`Ctrl+Shift+1`", "Replace selected occurrence of the search word, and move to the next"
":kbd:`Ctrl+Shift+G`", "Find previous occurrence of the search word" ":kbd:`Ctrl+Shift+G`", "Find the previous occurrence of the search word"
":kbd:`Shift+F3`", "Find the previous occurrence of the search word" ":kbd:`Shift+F3`", "Find the previous occurrence of the search word"
+2 -2
View File
@@ -209,7 +209,7 @@ class GuiMainMenu(QMenuBar):
# Document > Close # Document > Close
self.aCloseDoc = self.docuMenu.addAction(self.tr("Close Document")) self.aCloseDoc = self.docuMenu.addAction(self.tr("Close Document"))
self.aCloseDoc.setShortcut("Ctrl+W") self.aCloseDoc.setShortcut("Ctrl+W")
self.aCloseDoc.triggered.connect(lambda: self.mainGui.closeDocEditor()) self.aCloseDoc.triggered.connect(self.mainGui.closeDocEditor)
# Document > Separator # Document > Separator
self.docuMenu.addSeparator() self.docuMenu.addSeparator()
@@ -330,7 +330,7 @@ class GuiMainMenu(QMenuBar):
# View > Focus Mode # View > Focus Mode
self.aFocusMode = self.viewMenu.addAction(self.tr("Focus Mode")) self.aFocusMode = self.viewMenu.addAction(self.tr("Focus Mode"))
self.aFocusMode.setShortcut("F8") self.aFocusMode.setShortcut("F8")
self.aFocusMode.triggered.connect(lambda: self.mainGui.toggleFocusMode()) self.aFocusMode.triggered.connect(self.mainGui.toggleFocusMode)
# View > Toggle Full Screen # View > Toggle Full Screen
self.aFullScreen = self.viewMenu.addAction(self.tr("Full Screen Mode")) self.aFullScreen = self.viewMenu.addAction(self.tr("Full Screen Mode"))
-1
View File
@@ -115,7 +115,6 @@ class GuiSideBar(QWidget):
self.outerBox.setSpacing(CONFIG.pxInt(4)) self.outerBox.setSpacing(CONFIG.pxInt(4))
self.setLayout(self.outerBox) self.setLayout(self.outerBox)
self.updateTheme() self.updateTheme()
logger.debug("Ready: GuiSideBar") logger.debug("Ready: GuiSideBar")
+169 -161
View File
@@ -267,6 +267,8 @@ class GuiMain(QMainWindow):
self.docEditor.novelItemMetaChanged.connect(self.novelView.updateNovelItemMeta) self.docEditor.novelItemMetaChanged.connect(self.novelView.updateNovelItemMeta)
self.docEditor.statusMessage.connect(self.mainStatus.setStatusMessage) self.docEditor.statusMessage.connect(self.mainStatus.setStatusMessage)
self.docEditor.spellCheckStateChanged.connect(self.mainMenu.setSpellCheckState) self.docEditor.spellCheckStateChanged.connect(self.mainMenu.setSpellCheckState)
self.docEditor.closeDocumentRequest.connect(self.closeDocEditor)
self.docEditor.toggleFocusModeRequest.connect(self.toggleFocusMode)
self.docViewer.loadDocumentTagRequest.connect(self._followTag) self.docViewer.loadDocumentTagRequest.connect(self._followTag)
@@ -1119,12 +1121,6 @@ class GuiMain(QMainWindow):
self.outlineView.setTreeFocus() self.outlineView.setTreeFocus()
return return
def closeDocEditor(self) -> None:
"""Close the document editor. This does not hide the editor."""
self.closeDocument()
SHARED.project.data.setLastHandle(None, "editor")
return
def closeDocViewer(self, byUser: bool = True) -> bool: def closeDocViewer(self, byUser: bool = True) -> bool:
"""Close the document view panel.""" """Close the document view panel."""
self.docViewer.clearViewer() self.docViewer.clearViewer()
@@ -1139,13 +1135,44 @@ class GuiMain(QMainWindow):
return not self.splitView.isVisible() return not self.splitView.isVisible()
def toggleFocusMode(self) -> bool: def toggleFullScreenMode(self) -> None:
"""Toggle full screen mode"""
self.setWindowState(self.windowState() ^ Qt.WindowFullScreen)
return
##
# Events
##
def closeEvent(self, event: QCloseEvent):
"""Capture the closing event of the GUI and call the close
function to handle all the close process steps.
"""
if self.closeMain():
event.accept()
else:
event.ignore()
return
##
# Public Slots
##
@pyqtSlot()
def closeDocEditor(self) -> None:
"""Close the document editor. This does not hide the editor."""
self.closeDocument()
SHARED.project.data.setLastHandle(None, "editor")
return
@pyqtSlot()
def toggleFocusMode(self) -> None:
"""Handle toggle focus mode. The Main GUI Focus Mode hides tree, """Handle toggle focus mode. The Main GUI Focus Mode hides tree,
view, statusbar and menu. view, statusbar and menu.
""" """
if self.docEditor.docHandle is None: if self.docEditor.docHandle is None:
logger.error("No document open, so not activating Focus Mode") logger.error("No document open, so not activating Focus Mode")
return False return
self.isFocusMode = not self.isFocusMode self.isFocusMode = not self.isFocusMode
if self.isFocusMode: if self.isFocusMode:
@@ -1169,11 +1196,141 @@ class GuiMain(QMainWindow):
elif self.docViewer.docHandle is not None: elif self.docViewer.docHandle is not None:
self.splitView.setVisible(True) self.splitView.setVisible(True)
return True return
def toggleFullScreenMode(self) -> None: ##
"""Toggle full screen mode""" # Private Slots
self.setWindowState(self.windowState() ^ Qt.WindowFullScreen) ##
@pyqtSlot(str, nwDocMode)
def _followTag(self, tag: str, mode: nwDocMode) -> None:
"""Follow a tag after user interaction with a link."""
tHandle, sTitle = self._getTagSource(tag)
if tHandle is not None:
if mode == nwDocMode.EDIT:
self.openDocument(tHandle)
elif mode == nwDocMode.VIEW:
self.viewDocument(tHandle=tHandle, sTitle=sTitle)
return
@pyqtSlot(str, nwDocMode, str, bool)
def _openDocument(self, tHandle: str, mode: nwDocMode, sTitle: str, setFocus: bool) -> None:
"""Handle an open document request."""
if tHandle is not None:
if mode == nwDocMode.EDIT:
tLine = None
hItem = SHARED.project.index.getItemHeader(tHandle, sTitle)
if hItem is not None:
tLine = hItem.line
self.openDocument(tHandle, tLine=tLine, changeFocus=setFocus)
elif mode == nwDocMode.VIEW:
self.viewDocument(tHandle=tHandle, sTitle=sTitle)
return
@pyqtSlot(nwView)
def _changeView(self, view: nwView) -> None:
"""Handle the requested change of view from the GuiViewBar."""
if view == nwView.EDITOR:
# Only change the main stack, but not the project stack
self.mainStack.setCurrentWidget(self.splitMain)
elif view == nwView.PROJECT:
self.mainStack.setCurrentWidget(self.splitMain)
self.projStack.setCurrentWidget(self.projView)
elif view == nwView.NOVEL:
self.mainStack.setCurrentWidget(self.splitMain)
self.projStack.setCurrentWidget(self.novelView)
elif view == nwView.OUTLINE:
self.mainStack.setCurrentWidget(self.outlineView)
return
@pyqtSlot()
def _timeTick(self) -> None:
"""Process time tick of the main timer."""
if not SHARED.hasProject:
return
currTime = time()
editIdle = currTime - self.docEditor.lastActive > CONFIG.userIdleTime
userIdle = qApp.applicationState() != Qt.ApplicationActive
self.mainStatus.setUserIdle(editIdle or userIdle)
SHARED.updateIdleTime(currTime, editIdle or userIdle)
self.mainStatus.updateTime(idleTime=SHARED.projectIdleTime)
return
@pyqtSlot()
def _autoSaveProject(self) -> None:
"""Autosave of the project. This is a timer-activated slot."""
doSave = SHARED.hasProject
doSave &= SHARED.project.projChanged
doSave &= SHARED.project.storage.isOpen()
if doSave:
logger.debug("Autosaving project")
self.saveProject(autoSave=True)
return
@pyqtSlot()
def _autoSaveDocument(self) -> None:
"""Autosave of the document. This is a timer-activated slot."""
if SHARED.hasProject and self.docEditor.docChanged:
logger.debug("Autosaving document")
self.saveDocument()
return
@pyqtSlot()
def _updateStatusWordCount(self) -> None:
"""Update the word count on the status bar."""
if not SHARED.hasProject:
self.mainStatus.setProjectStats(0, 0)
SHARED.project.updateWordCounts()
if CONFIG.incNotesWCount:
iTotal = sum(SHARED.project.data.initCounts)
cTotal = sum(SHARED.project.data.currCounts)
self.mainStatus.setProjectStats(cTotal, cTotal - iTotal)
else:
iNovel, _ = SHARED.project.data.initCounts
cNovel, _ = SHARED.project.data.currCounts
self.mainStatus.setProjectStats(cNovel, cNovel - iNovel)
return
@pyqtSlot()
def _keyPressReturn(self) -> None:
"""Forward the return/enter keypress to the function that opens
the currently selected item.
"""
self.openSelectedItem()
return
@pyqtSlot()
def _keyPressEscape(self) -> None:
"""Process escape keypress in the main window."""
if self.docEditor.docSearch.isVisible():
self.docEditor.closeSearch()
elif self.isFocusMode:
self.toggleFocusMode()
return
@pyqtSlot(int)
def _mainStackChanged(self, index: int) -> None:
"""Process main window tab change."""
if index == self.idxOutlineView:
if SHARED.hasProject:
self.outlineView.refreshTree()
return
@pyqtSlot(int)
def _projStackChanged(self, index: int) -> None:
"""Process project view tab change."""
sHandle = None
if index == self.idxProjView:
sHandle = self.projView.getSelectedHandle()
elif index == self.idxNovelView:
sHandle, _ = self.novelView.getSelectedHandle()
self.itemDetails.updateViewBox(sHandle)
return return
## ##
@@ -1328,153 +1485,4 @@ class GuiMain(QMainWindow):
return None, None return None, None
return tHandle, sTitle return tHandle, sTitle
##
# Events
##
def closeEvent(self, event: QCloseEvent):
"""Capture the closing event of the GUI and call the close
function to handle all the close process steps.
"""
if self.closeMain():
event.accept()
else:
event.ignore()
return
##
# Private Slots
##
@pyqtSlot(str, nwDocMode)
def _followTag(self, tag: str, mode: nwDocMode) -> None:
"""Follow a tag after user interaction with a link."""
tHandle, sTitle = self._getTagSource(tag)
if tHandle is not None:
if mode == nwDocMode.EDIT:
self.openDocument(tHandle)
elif mode == nwDocMode.VIEW:
self.viewDocument(tHandle=tHandle, sTitle=sTitle)
return
@pyqtSlot(str, nwDocMode, str, bool)
def _openDocument(self, tHandle: str, mode: nwDocMode, sTitle: str, setFocus: bool) -> None:
"""Handle an open document request."""
if tHandle is not None:
if mode == nwDocMode.EDIT:
tLine = None
hItem = SHARED.project.index.getItemHeader(tHandle, sTitle)
if hItem is not None:
tLine = hItem.line
self.openDocument(tHandle, tLine=tLine, changeFocus=setFocus)
elif mode == nwDocMode.VIEW:
self.viewDocument(tHandle=tHandle, sTitle=sTitle)
return
@pyqtSlot(nwView)
def _changeView(self, view: nwView) -> None:
"""Handle the requested change of view from the GuiViewBar."""
if view == nwView.EDITOR:
# Only change the main stack, but not the project stack
self.mainStack.setCurrentWidget(self.splitMain)
elif view == nwView.PROJECT:
self.mainStack.setCurrentWidget(self.splitMain)
self.projStack.setCurrentWidget(self.projView)
elif view == nwView.NOVEL:
self.mainStack.setCurrentWidget(self.splitMain)
self.projStack.setCurrentWidget(self.novelView)
elif view == nwView.OUTLINE:
self.mainStack.setCurrentWidget(self.outlineView)
return
@pyqtSlot()
def _timeTick(self) -> None:
"""Process time tick of the main timer."""
if not SHARED.hasProject:
return
currTime = time()
editIdle = currTime - self.docEditor.lastActive > CONFIG.userIdleTime
userIdle = qApp.applicationState() != Qt.ApplicationActive
self.mainStatus.setUserIdle(editIdle or userIdle)
SHARED.updateIdleTime(currTime, editIdle or userIdle)
self.mainStatus.updateTime(idleTime=SHARED.projectIdleTime)
return
@pyqtSlot()
def _autoSaveProject(self) -> None:
"""Autosave of the project. This is a timer-activated slot."""
doSave = SHARED.hasProject
doSave &= SHARED.project.projChanged
doSave &= SHARED.project.storage.isOpen()
if doSave:
logger.debug("Autosaving project")
self.saveProject(autoSave=True)
return
@pyqtSlot()
def _autoSaveDocument(self) -> None:
"""Autosave of the document. This is a timer-activated slot."""
if SHARED.hasProject and self.docEditor.docChanged:
logger.debug("Autosaving document")
self.saveDocument()
return
@pyqtSlot()
def _updateStatusWordCount(self) -> None:
"""Update the word count on the status bar."""
if not SHARED.hasProject:
self.mainStatus.setProjectStats(0, 0)
SHARED.project.updateWordCounts()
if CONFIG.incNotesWCount:
iTotal = sum(SHARED.project.data.initCounts)
cTotal = sum(SHARED.project.data.currCounts)
self.mainStatus.setProjectStats(cTotal, cTotal - iTotal)
else:
iNovel, _ = SHARED.project.data.initCounts
cNovel, _ = SHARED.project.data.currCounts
self.mainStatus.setProjectStats(cNovel, cNovel - iNovel)
return
@pyqtSlot()
def _keyPressReturn(self) -> None:
"""Forward the return/enter keypress to the function that opens
the currently selected item.
"""
self.openSelectedItem()
return
@pyqtSlot()
def _keyPressEscape(self) -> None:
"""Process escape keypress in the main window."""
if self.docEditor.docSearch.isVisible():
self.docEditor.closeSearch()
elif self.isFocusMode:
self.toggleFocusMode()
return
@pyqtSlot(int)
def _mainStackChanged(self, index: int) -> None:
"""Process main window tab change."""
if index == self.idxOutlineView:
if SHARED.hasProject:
self.outlineView.refreshTree()
return
@pyqtSlot(int)
def _projStackChanged(self, index: int) -> None:
"""Process project view tab change."""
sHandle = None
if index == self.idxProjView:
sHandle = self.projView.getSelectedHandle()
elif index == self.idxNovelView:
sHandle, _ = self.novelView.getSelectedHandle()
self.itemDetails.updateViewBox(sHandle)
return
# END Class GuiMain # END Class GuiMain
+7 -3
View File
@@ -594,14 +594,18 @@ def testGuiMain_Features(qtbot, nwGUI, projPath, mockRnd):
# ========== # ==========
# No document open, so not allowing focus mode # No document open, so not allowing focus mode
assert nwGUI.toggleFocusMode() is False nwGUI.toggleFocusMode()
assert nwGUI.treePane.isVisible() is True
assert nwGUI.mainStatus.isVisible() is True
assert nwGUI.mainMenu.isVisible() is True
assert nwGUI.sideBar.isVisible() is True
# Open a file in editor and viewer # Open a file in editor and viewer
assert nwGUI.openDocument(C.hSceneDoc) assert nwGUI.openDocument(C.hSceneDoc)
assert nwGUI.viewDocument(C.hSceneDoc) assert nwGUI.viewDocument(C.hSceneDoc)
# Enable focus mode # Enable focus mode
assert nwGUI.toggleFocusMode() is True nwGUI.toggleFocusMode()
assert nwGUI.treePane.isVisible() is False assert nwGUI.treePane.isVisible() is False
assert nwGUI.mainStatus.isVisible() is False assert nwGUI.mainStatus.isVisible() is False
assert nwGUI.mainMenu.isVisible() is False assert nwGUI.mainMenu.isVisible() is False
@@ -609,7 +613,7 @@ def testGuiMain_Features(qtbot, nwGUI, projPath, mockRnd):
assert nwGUI.splitView.isVisible() is False assert nwGUI.splitView.isVisible() is False
# Disable focus mode # Disable focus mode
assert nwGUI.toggleFocusMode() is True nwGUI.toggleFocusMode()
assert nwGUI.treePane.isVisible() is True assert nwGUI.treePane.isVisible() is True
assert nwGUI.mainStatus.isVisible() is True assert nwGUI.mainStatus.isVisible() is True
assert nwGUI.mainMenu.isVisible() is True assert nwGUI.mainMenu.isVisible() is True