From 8afe3ed039518f2cba170744101f45cfc3ca3696 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sun, 17 Mar 2024 15:21:42 +0100 Subject: [PATCH] Let the shared class handle focus mode change to disconnect editor header from main GUI --- novelwriter/gui/doceditor.py | 24 +++++++++---------- novelwriter/guimain.py | 38 ++++++++++++++---------------- novelwriter/shared.py | 19 +++++++++++++++ tests/test_gui/test_gui_guimain.py | 2 +- 4 files changed, 49 insertions(+), 34 deletions(-) diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index 5112d54a..910ae4a0 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -548,8 +548,8 @@ class GuiDocEditor(QPlainTextEdit): sH = hBar.height() if hBar.isVisible() else 0 tM = self._vpMargin - if CONFIG.textWidth > 0 or self.mainGui.isFocusMode: - tW = CONFIG.getTextWidth(self.mainGui.isFocusMode) + if CONFIG.textWidth > 0 or SHARED.focusMode: + tW = CONFIG.getTextWidth(SHARED.focusMode) tM = max((wW - sW - tW)//2, self._vpMargin) tB = self.frameWidth() @@ -2894,6 +2894,9 @@ class GuiDocEditHeader(QWidget): self.setLayout(self.outerBox) + # Other Signals + SHARED.focusModeChanged.connect(self._focusModeChanged) + # Fix Margins and Size # This is needed for high DPI systems. See issue #499. self.setContentsMargins(0, 0, 0, 0) @@ -2997,17 +3000,6 @@ class GuiDocEditHeader(QWidget): return - def updateFocusMode(self) -> None: - """Update the minimise/maximise icon of the Focus Mode button. - This function is called by the GuiMain class via the - toggleFocusMode function and should not be activated directly. - """ - if self.mainGui.isFocusMode: - self.minmaxButton.setIcon(SHARED.theme.getIcon("minimise")) - else: - self.minmaxButton.setIcon(SHARED.theme.getIcon("maximise")) - return - ## # Private Slots ## @@ -3025,6 +3017,12 @@ class GuiDocEditHeader(QWidget): self.docEditor.setCursorLine(blockNumber + 1) return + @pyqtSlot(bool) + def _focusModeChanged(self, focusMode: bool) -> None: + """Update minimise/maximise icon of the Focus Mode button.""" + self.minmaxButton.setIcon(SHARED.theme.getIcon("minimise" if focusMode else "maximise")) + return + ## # Events ## diff --git a/novelwriter/guimain.py b/novelwriter/guimain.py index 5faf9a28..c6ea31f2 100644 --- a/novelwriter/guimain.py +++ b/novelwriter/guimain.py @@ -104,9 +104,6 @@ class GuiMain(QMainWindow): # Initialise UserData Instance SHARED.initSharedData(self, GuiTheme()) - # Core Settings - self.isFocusMode = False - # Prepare Main Window self.resize(*CONFIG.mainWinSize) self._updateWindowTitle() @@ -233,6 +230,7 @@ class GuiMain(QMainWindow): SHARED.projectStatusChanged.connect(self.mainStatus.updateProjectStatus) SHARED.projectStatusMessage.connect(self.mainStatus.setStatusMessage) SHARED.spellLanguageChanged.connect(self.mainStatus.setLanguage) + SHARED.focusModeChanged.connect(self._focusModeChanged) SHARED.indexChangedTags.connect(self.docViewerPanel.updateChangedTags) SHARED.indexScannedText.connect(self.docViewerPanel.projectItemChanged) SHARED.indexScannedText.connect(self.projView.updateItemValues) @@ -532,8 +530,8 @@ class GuiMain(QMainWindow): return False # Disable focus mode if it is active - if self.isFocusMode: - self.toggleFocusMode() + if SHARED.focusMode: + SHARED.setFocusMode(False) self.docEditor.saveCursorPosition() if self.docEditor.docChanged: @@ -747,7 +745,7 @@ class GuiMain(QMainWindow): if not SHARED.hasProject: logger.error("No project open") return False - if tHandle is None and (self.docEditor.anyFocus() or self.isFocusMode): + if tHandle is None and (self.docEditor.anyFocus() or SHARED.focusMode): tHandle = self.docEditor.docHandle self.projView.renameTreeItem(tHandle) return True @@ -919,7 +917,7 @@ class GuiMain(QMainWindow): logger.info("Exiting novelWriter") - if not self.isFocusMode: + if not SHARED.focusMode: CONFIG.setMainPanePos(self.splitMain.sizes()) CONFIG.setOutlinePanePos(self.outlineView.splitSizes()) if self.docViewerPanel.isVisible(): @@ -997,30 +995,31 @@ class GuiMain(QMainWindow): @pyqtSlot() def toggleFocusMode(self) -> None: - """Handle toggle focus mode. The Main GUI Focus Mode hides tree, + """Toggle focus mode.""" + if self.docEditor.docHandle: + SHARED.setFocusMode(not SHARED.focusMode) + return + + @pyqtSlot(bool) + def _focusModeChanged(self, focusMode: bool) -> None: + """Handle change of focus mode. The Main GUI Focus Mode hides tree, view, statusbar and menu. """ - if self.docEditor.docHandle is None: - logger.error("No document open, so not activating Focus Mode") - return - - self.isFocusMode = not self.isFocusMode - if self.isFocusMode: + if focusMode: logger.debug("Activating Focus Mode") self.switchFocus(nwWidget.EDITOR) else: logger.debug("Deactivating Focus Mode") cursorVisible = self.docEditor.cursorIsVisible() - isVisible = not self.isFocusMode + isVisible = not focusMode self.treePane.setVisible(isVisible) self.mainStatus.setVisible(isVisible) self.mainMenu.setVisible(isVisible) self.sideBar.setVisible(isVisible) - hideDocFooter = self.isFocusMode and CONFIG.hideFocusFooter + hideDocFooter = focusMode and CONFIG.hideFocusFooter self.docEditor.docFooter.setVisible(not hideDocFooter) - self.docEditor.docHeader.updateFocusMode() if self.splitView.isVisible(): self.splitView.setVisible(False) @@ -1029,7 +1028,6 @@ class GuiMain(QMainWindow): if cursorVisible: self.docEditor.ensureCursorVisibleNoCentre() - return @pyqtSlot(nwWidget) @@ -1279,8 +1277,8 @@ class GuiMain(QMainWindow): """Process escape keypress in the main window.""" if self.docEditor.docSearch.isVisible(): self.docEditor.closeSearch() - elif self.isFocusMode: - self.toggleFocusMode() + elif SHARED.focusMode: + SHARED.setFocusMode(False) return @pyqtSlot(int) diff --git a/novelwriter/shared.py b/novelwriter/shared.py index c7f7f70d..31b3c88a 100644 --- a/novelwriter/shared.py +++ b/novelwriter/shared.py @@ -57,6 +57,7 @@ class SharedData(QObject): projectStatusChanged = pyqtSignal(bool) projectStatusMessage = pyqtSignal(str) spellLanguageChanged = pyqtSignal(str, str) + focusModeChanged = pyqtSignal(bool) indexScannedText = pyqtSignal(str) indexChangedTags = pyqtSignal(list, list) indexCleared = pyqtSignal() @@ -76,6 +77,7 @@ class SharedData(QObject): self._lastAlert = "" self._idleTime = 0.0 self._idleRefTime = time() + self._focusMode = False return @@ -111,6 +113,11 @@ class SharedData(QObject): raise Exception("SharedData class not fully initialised") return self._spelling + @property + def focusMode(self) -> bool: + """Return the Focus Mode state.""" + return self._focusMode + @property def hasProject(self) -> bool: """Return True if the project instance is populated.""" @@ -131,6 +138,17 @@ class SharedData(QObject): """Return the last alert message.""" return self._lastAlert + ## + # Setters + ## + + def setFocusMode(self, state: bool) -> None: + """Set focus mode on or off.""" + if state is not self._focusMode: + self._focusMode = state + self.focusModeChanged.emit(state) + return + ## # Methods ## @@ -323,6 +341,7 @@ class SharedData(QObject): self._project = NWProject() self._spelling = NWSpellEnchant(self._project) self.updateSpellCheckLanguage() + self._focusMode = False return def _resetIdleTimer(self) -> None: diff --git a/tests/test_gui/test_gui_guimain.py b/tests/test_gui/test_gui_guimain.py index 8d9d50fd..cc9097c7 100644 --- a/tests/test_gui/test_gui_guimain.py +++ b/tests/test_gui/test_gui_guimain.py @@ -574,7 +574,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd): def testGuiMain_Features(qtbot, nwGUI, projPath, mockRnd): """Test various features of the main window.""" buildTestProject(nwGUI, projPath) - assert nwGUI.isFocusMode is False + assert SHARED.focusMode is False # Focus Mode # ==========