Add focus indication to editor and viewer header
This commit is contained in:
@@ -55,6 +55,7 @@ from novelwriter.common import minmax, transferCase
|
|||||||
from novelwriter.constants import nwConst, nwKeyWords, nwShortcode, nwUnicode
|
from novelwriter.constants import nwConst, nwKeyWords, nwShortcode, nwUnicode
|
||||||
from novelwriter.core.document import NWDocument
|
from novelwriter.core.document import NWDocument
|
||||||
from novelwriter.enum import nwComment, nwDocAction, nwDocInsert, nwDocMode, nwItemClass, nwTrinary
|
from novelwriter.enum import nwComment, nwDocAction, nwDocInsert, nwDocMode, nwItemClass, nwTrinary
|
||||||
|
from novelwriter.extensions.configlayout import NColourLabel
|
||||||
from novelwriter.extensions.eventfilters import WheelEventFilter
|
from novelwriter.extensions.eventfilters import WheelEventFilter
|
||||||
from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton
|
from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton
|
||||||
from novelwriter.gui.dochighlight import BLOCK_META, BLOCK_TITLE
|
from novelwriter.gui.dochighlight import BLOCK_META, BLOCK_TITLE
|
||||||
@@ -210,6 +211,7 @@ class GuiDocEditor(QPlainTextEdit):
|
|||||||
# Function Mapping
|
# Function Mapping
|
||||||
self.closeSearch = self.docSearch.closeSearch
|
self.closeSearch = self.docSearch.closeSearch
|
||||||
self.searchVisible = self.docSearch.isVisible
|
self.searchVisible = self.docSearch.isVisible
|
||||||
|
self.changeFocusState = self.docHeader.changeFocusState
|
||||||
|
|
||||||
# Finalise
|
# Finalise
|
||||||
self.updateSyntaxColours()
|
self.updateSyntaxColours()
|
||||||
@@ -2785,8 +2787,7 @@ class GuiDocEditHeader(QWidget):
|
|||||||
self.setAutoFillBackground(True)
|
self.setAutoFillBackground(True)
|
||||||
|
|
||||||
# Title Label
|
# Title Label
|
||||||
self.itemTitle = QLabel("", self)
|
self.itemTitle = NColourLabel("", self, faded=SHARED.theme.fadedText)
|
||||||
self.itemTitle.setIndent(0)
|
|
||||||
self.itemTitle.setMargin(0)
|
self.itemTitle.setMargin(0)
|
||||||
self.itemTitle.setContentsMargins(0, 0, 0, 0)
|
self.itemTitle.setContentsMargins(0, 0, 0, 0)
|
||||||
self.itemTitle.setAutoFillBackground(True)
|
self.itemTitle.setAutoFillBackground(True)
|
||||||
@@ -2924,6 +2925,11 @@ class GuiDocEditHeader(QWidget):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def changeFocusState(self, state: bool) -> None:
|
||||||
|
"""Toggle focus state."""
|
||||||
|
self.itemTitle.setColorState(state)
|
||||||
|
return
|
||||||
|
|
||||||
def setHandle(self, tHandle: str) -> None:
|
def setHandle(self, tHandle: str) -> None:
|
||||||
"""Set the document title from the handle, or alternatively, set
|
"""Set the document title from the handle, or alternatively, set
|
||||||
the whole document path within the project.
|
the whole document path within the project.
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ from enum import Enum
|
|||||||
from PyQt5.QtCore import QPoint, Qt, QUrl, pyqtSignal, pyqtSlot
|
from PyQt5.QtCore import QPoint, Qt, QUrl, pyqtSignal, pyqtSlot
|
||||||
from PyQt5.QtGui import QCursor, QMouseEvent, QPalette, QResizeEvent, QTextCursor
|
from PyQt5.QtGui import QCursor, QMouseEvent, QPalette, QResizeEvent, QTextCursor
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
QAction, QApplication, QFrame, QHBoxLayout, QLabel, QMenu, QTextBrowser,
|
QAction, QApplication, QFrame, QHBoxLayout, QMenu, QTextBrowser,
|
||||||
QToolButton, QWidget
|
QToolButton, QWidget
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -42,6 +42,7 @@ from novelwriter.constants import nwHeaders, nwUnicode
|
|||||||
from novelwriter.core.toqdoc import TextDocumentTheme, ToQTextDocument
|
from novelwriter.core.toqdoc import TextDocumentTheme, ToQTextDocument
|
||||||
from novelwriter.enum import nwDocAction, nwDocMode, nwItemType
|
from novelwriter.enum import nwDocAction, nwDocMode, nwItemType
|
||||||
from novelwriter.error import logException
|
from novelwriter.error import logException
|
||||||
|
from novelwriter.extensions.configlayout import NColourLabel
|
||||||
from novelwriter.extensions.eventfilters import WheelEventFilter
|
from novelwriter.extensions.eventfilters import WheelEventFilter
|
||||||
from novelwriter.extensions.modified import NIconToolButton
|
from novelwriter.extensions.modified import NIconToolButton
|
||||||
from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON
|
from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON
|
||||||
@@ -92,6 +93,9 @@ class GuiDocViewer(QTextBrowser):
|
|||||||
self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
|
self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
|
||||||
self.customContextMenuRequested.connect(self._openContextMenu)
|
self.customContextMenuRequested.connect(self._openContextMenu)
|
||||||
|
|
||||||
|
# Function Mapping
|
||||||
|
self.changeFocusState = self.docHeader.changeFocusState
|
||||||
|
|
||||||
self.initViewer()
|
self.initViewer()
|
||||||
|
|
||||||
logger.debug("Ready: GuiDocViewer")
|
logger.debug("Ready: GuiDocViewer")
|
||||||
@@ -597,9 +601,7 @@ class GuiDocViewHeader(QWidget):
|
|||||||
self.setAutoFillBackground(True)
|
self.setAutoFillBackground(True)
|
||||||
|
|
||||||
# Title Label
|
# Title Label
|
||||||
self.itemTitle = QLabel(self)
|
self.itemTitle = NColourLabel("", self, faded=SHARED.theme.fadedText)
|
||||||
self.itemTitle.setText("")
|
|
||||||
self.itemTitle.setIndent(0)
|
|
||||||
self.itemTitle.setMargin(0)
|
self.itemTitle.setMargin(0)
|
||||||
self.itemTitle.setContentsMargins(0, 0, 0, 0)
|
self.itemTitle.setContentsMargins(0, 0, 0, 0)
|
||||||
self.itemTitle.setAutoFillBackground(True)
|
self.itemTitle.setAutoFillBackground(True)
|
||||||
@@ -738,6 +740,11 @@ class GuiDocViewHeader(QWidget):
|
|||||||
self.itemTitle.setPalette(palette)
|
self.itemTitle.setPalette(palette)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def changeFocusState(self, state: bool) -> None:
|
||||||
|
"""Toggle focus state."""
|
||||||
|
self.itemTitle.setColorState(state)
|
||||||
|
return
|
||||||
|
|
||||||
def setHandle(self, tHandle: str) -> None:
|
def setHandle(self, tHandle: str) -> None:
|
||||||
"""Sets the document title from the handle, or alternatively,
|
"""Sets the document title from the handle, or alternatively,
|
||||||
set the whole document path.
|
set the whole document path.
|
||||||
|
|||||||
@@ -326,6 +326,11 @@ class GuiMain(QMainWindow):
|
|||||||
|
|
||||||
def postLaunchTasks(self, cmdOpen: str | None) -> None:
|
def postLaunchTasks(self, cmdOpen: str | None) -> None:
|
||||||
"""Process tasks after the main window has been created."""
|
"""Process tasks after the main window has been created."""
|
||||||
|
QApplication.processEvents()
|
||||||
|
app = QApplication.instance()
|
||||||
|
if isinstance(app, QApplication):
|
||||||
|
app.focusChanged.connect(self._appFocusChanged)
|
||||||
|
|
||||||
# Check that config loaded fine
|
# Check that config loaded fine
|
||||||
if CONFIG.hasError:
|
if CONFIG.hasError:
|
||||||
SHARED.error(CONFIG.errorText())
|
SHARED.error(CONFIG.errorText())
|
||||||
@@ -948,6 +953,24 @@ class GuiMain(QMainWindow):
|
|||||||
# Private Slots
|
# Private Slots
|
||||||
##
|
##
|
||||||
|
|
||||||
|
@pyqtSlot("QWidget*", "QWidget*")
|
||||||
|
def _appFocusChanged(self, old: QWidget, new: QWidget) -> None:
|
||||||
|
"""Alert main widgets that they have received or lost focus."""
|
||||||
|
if isinstance(new, QWidget):
|
||||||
|
docEditor = False
|
||||||
|
docViewer = False
|
||||||
|
if self.docEditor.isAncestorOf(new):
|
||||||
|
docEditor = True
|
||||||
|
elif self.docViewer.isAncestorOf(new):
|
||||||
|
docViewer = True
|
||||||
|
|
||||||
|
self.docEditor.changeFocusState(docEditor)
|
||||||
|
self.docViewer.changeFocusState(docViewer)
|
||||||
|
|
||||||
|
logger.debug("Main focus switched to: %s", type(new).__name__)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
@pyqtSlot(bool)
|
@pyqtSlot(bool)
|
||||||
def _focusModeChanged(self, focusMode: bool) -> None:
|
def _focusModeChanged(self, focusMode: bool) -> None:
|
||||||
"""Handle change of focus mode. The Main GUI Focus Mode hides
|
"""Handle change of focus mode. The Main GUI Focus Mode hides
|
||||||
|
|||||||
@@ -62,15 +62,17 @@ def testBaseInit_Launch(caplog, monkeypatch, fncPath):
|
|||||||
CONFIG.osWindows = osWindows
|
CONFIG.osWindows = osWindows
|
||||||
|
|
||||||
# Normal Launch
|
# Normal Launch
|
||||||
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.__init__", lambda *a: None)
|
with monkeypatch.context() as mp:
|
||||||
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.setApplicationName", lambda *a: None)
|
mp.setattr("PyQt5.QtWidgets.QApplication.__init__", lambda *a: None)
|
||||||
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.setApplicationVersion", lambda *a: None)
|
mp.setattr("PyQt5.QtWidgets.QApplication.setApplicationName", lambda *a: None)
|
||||||
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.setWindowIcon", lambda *a: None)
|
mp.setattr("PyQt5.QtWidgets.QApplication.setApplicationVersion", lambda *a: None)
|
||||||
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.setOrganizationDomain", lambda *a: None)
|
mp.setattr("PyQt5.QtWidgets.QApplication.setWindowIcon", lambda *a: None)
|
||||||
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.exec", lambda *a: 0)
|
mp.setattr("PyQt5.QtWidgets.QApplication.setOrganizationDomain", lambda *a: None)
|
||||||
with pytest.raises(SystemExit) as ex:
|
mp.setattr("PyQt5.QtWidgets.QApplication.exec", lambda *a: 0)
|
||||||
main([f"--config={fncPath}", f"--data={fncPath}"])
|
# mp.setattr("PyQt5.QtWidgets.QApplication.focusChange.connect", lambda *a: None)
|
||||||
assert ex.value.code == 0
|
with pytest.raises(SystemExit) as ex:
|
||||||
|
main([f"--config={fncPath}", f"--data={fncPath}"])
|
||||||
|
assert ex.value.code == 0
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.base
|
@pytest.mark.base
|
||||||
|
|||||||
Reference in New Issue
Block a user