Add editor/viewer toggle feature
This commit is contained in:
@@ -26,7 +26,7 @@ linkvisited = 102, 153, 204
|
||||
|
||||
[GUI]
|
||||
helptext = 164, 164, 164
|
||||
fadedtext = 128, 128, 128
|
||||
fadedtext = 148, 148, 148
|
||||
errortext = 255, 164, 164
|
||||
statusnone = 150, 152, 150
|
||||
statussaved = 39, 135, 78
|
||||
|
||||
@@ -26,7 +26,7 @@ linkvisited = 66, 113, 174
|
||||
|
||||
[GUI]
|
||||
helptext = 92, 92, 92
|
||||
fadedtext = 128, 128, 128
|
||||
fadedtext = 108, 108, 108
|
||||
errortext = 255, 92, 92
|
||||
statusnone = 120, 120, 120
|
||||
statussaved = 200, 15, 39
|
||||
|
||||
+4
-5
@@ -148,12 +148,11 @@ class nwView(Enum):
|
||||
SEARCH = 4
|
||||
|
||||
|
||||
class nwWidget(Enum):
|
||||
class nwFocus(Enum):
|
||||
|
||||
TREE = 1
|
||||
EDITOR = 2
|
||||
VIEWER = 3
|
||||
OUTLINE = 4
|
||||
TREE = 1
|
||||
DOCUMENT = 2
|
||||
OUTLINE = 3
|
||||
|
||||
|
||||
class nwOutline(Enum):
|
||||
|
||||
@@ -34,7 +34,7 @@ from PyQt5.QtWidgets import (
|
||||
QVBoxLayout, QWidget
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG
|
||||
from novelwriter import CONFIG, SHARED
|
||||
|
||||
DEFAULT_SCALE = 0.9
|
||||
|
||||
@@ -266,7 +266,7 @@ class NColourLabel(QLabel):
|
||||
self._color = color or default
|
||||
self._faded = faded or default
|
||||
|
||||
font = self.font()
|
||||
font = SHARED.theme.guiFont
|
||||
font.setPointSizeF(scale*font.pointSizeF())
|
||||
font.setWeight(QFont.Weight.Bold if bold else QFont.Weight.Normal)
|
||||
if color:
|
||||
@@ -285,7 +285,6 @@ class NColourLabel(QLabel):
|
||||
"""Change the colour state."""
|
||||
if self._state is not state:
|
||||
self._state = state
|
||||
print("State:", state, type(self.parent()).__name__)
|
||||
colour = self.palette()
|
||||
colour.setColor(QPalette.ColorRole.WindowText, self._color if state else self._faded)
|
||||
self.setPalette(colour)
|
||||
|
||||
@@ -282,6 +282,10 @@ class GuiDocViewer(QTextBrowser):
|
||||
return False
|
||||
return True
|
||||
|
||||
def anyFocus(self) -> bool:
|
||||
"""Check if any widget or child widget has focus."""
|
||||
return self.hasFocus() or self.isAncestorOf(QApplication.focusWidget())
|
||||
|
||||
def clearNavHistory(self) -> None:
|
||||
"""Clear the navigation history."""
|
||||
self.docHistory.clear()
|
||||
|
||||
@@ -35,7 +35,7 @@ from PyQt5.QtWidgets import QAction, QMenuBar
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.common import openExternalPath
|
||||
from novelwriter.constants import nwConst, nwKeyWords, nwLabels, nwUnicode, trConst
|
||||
from novelwriter.enum import nwDocAction, nwDocInsert, nwView, nwWidget
|
||||
from novelwriter.enum import nwDocAction, nwDocInsert, nwFocus, nwView
|
||||
from novelwriter.extensions.eventfilters import StatusTipFilter
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
@@ -54,7 +54,7 @@ class GuiMainMenu(QMenuBar):
|
||||
requestDocInsert = pyqtSignal(nwDocInsert)
|
||||
requestDocInsertText = pyqtSignal(str)
|
||||
requestDocKeyWordInsert = pyqtSignal(str)
|
||||
requestFocusChange = pyqtSignal(nwWidget)
|
||||
requestFocusChange = pyqtSignal(nwFocus)
|
||||
requestViewChange = pyqtSignal(nwView)
|
||||
|
||||
def __init__(self, mainGui: GuiMain) -> None:
|
||||
@@ -303,24 +303,24 @@ class GuiMainMenu(QMenuBar):
|
||||
self.viewMenu = self.addMenu(self.tr("&View"))
|
||||
|
||||
# View > TreeView
|
||||
self.aFocusTree = self.viewMenu.addAction(self.tr("Go to Project Tree"))
|
||||
self.aFocusTree = self.viewMenu.addAction(self.tr("Go to Tree View"))
|
||||
self.aFocusTree.setShortcut("Ctrl+T")
|
||||
self.aFocusTree.triggered.connect(
|
||||
lambda: self.requestFocusChange.emit(nwWidget.TREE)
|
||||
lambda: self.requestFocusChange.emit(nwFocus.TREE)
|
||||
)
|
||||
|
||||
# View > Document Editor
|
||||
self.aFocusEditor = self.viewMenu.addAction(self.tr("Go to Document Editor"))
|
||||
self.aFocusEditor.setShortcut("Ctrl+E")
|
||||
self.aFocusEditor.triggered.connect(
|
||||
lambda: self.requestFocusChange.emit(nwWidget.EDITOR)
|
||||
self.aFocusDocument = self.viewMenu.addAction(self.tr("Go to Document"))
|
||||
self.aFocusDocument.setShortcut("Ctrl+E")
|
||||
self.aFocusDocument.triggered.connect(
|
||||
lambda: self.requestFocusChange.emit(nwFocus.DOCUMENT)
|
||||
)
|
||||
|
||||
# View > Outline
|
||||
self.aFocusOutline = self.viewMenu.addAction(self.tr("Go to Outline"))
|
||||
self.aFocusOutline.setShortcut("Ctrl+Shift+T")
|
||||
self.aFocusOutline.triggered.connect(
|
||||
lambda: self.requestFocusChange.emit(nwWidget.OUTLINE)
|
||||
lambda: self.requestFocusChange.emit(nwFocus.OUTLINE)
|
||||
)
|
||||
|
||||
# View > Separator
|
||||
|
||||
+14
-11
@@ -44,7 +44,7 @@ from novelwriter.dialogs.about import GuiAbout
|
||||
from novelwriter.dialogs.preferences import GuiPreferences
|
||||
from novelwriter.dialogs.projectsettings import GuiProjectSettings
|
||||
from novelwriter.dialogs.wordlist import GuiWordList
|
||||
from novelwriter.enum import nwDocAction, nwDocInsert, nwDocMode, nwItemType, nwView, nwWidget
|
||||
from novelwriter.enum import nwDocAction, nwDocInsert, nwDocMode, nwFocus, nwItemType, nwView
|
||||
from novelwriter.gui.doceditor import GuiDocEditor
|
||||
from novelwriter.gui.docviewer import GuiDocViewer
|
||||
from novelwriter.gui.docviewerpanel import GuiDocViewerPanel
|
||||
@@ -978,7 +978,8 @@ class GuiMain(QMainWindow):
|
||||
"""
|
||||
if focusMode:
|
||||
logger.debug("Activating Focus Mode")
|
||||
self._switchFocus(nwWidget.EDITOR)
|
||||
self._changeView(nwView.EDITOR)
|
||||
self.docEditor.setFocus()
|
||||
else:
|
||||
logger.debug("Deactivating Focus Mode")
|
||||
|
||||
@@ -1001,10 +1002,10 @@ class GuiMain(QMainWindow):
|
||||
self.docEditor.ensureCursorVisibleNoCentre()
|
||||
return
|
||||
|
||||
@pyqtSlot(nwWidget)
|
||||
def _switchFocus(self, paneNo: nwWidget) -> None:
|
||||
@pyqtSlot(nwFocus)
|
||||
def _switchFocus(self, paneNo: nwFocus) -> None:
|
||||
"""Switch focus between main GUI views."""
|
||||
if paneNo == nwWidget.TREE:
|
||||
if paneNo == nwFocus.TREE:
|
||||
if self.projStack.currentWidget() is self.projView:
|
||||
if self.projView.treeHasFocus():
|
||||
self._changeView(nwView.NOVEL)
|
||||
@@ -1020,13 +1021,15 @@ class GuiMain(QMainWindow):
|
||||
else:
|
||||
self._changeView(nwView.PROJECT)
|
||||
self.projView.setTreeFocus()
|
||||
elif paneNo == nwWidget.EDITOR:
|
||||
elif paneNo == nwFocus.DOCUMENT:
|
||||
self._changeView(nwView.EDITOR)
|
||||
self.docEditor.setFocus()
|
||||
elif paneNo == nwWidget.VIEWER:
|
||||
self._changeView(nwView.EDITOR)
|
||||
self.docViewer.setFocus()
|
||||
elif paneNo == nwWidget.OUTLINE:
|
||||
if self.docEditor.anyFocus():
|
||||
self.docViewer.setFocus()
|
||||
elif self.docViewer.anyFocus():
|
||||
self.docEditor.setFocus()
|
||||
else:
|
||||
self.docEditor.setFocus()
|
||||
elif paneNo == nwFocus.OUTLINE:
|
||||
self._changeView(nwView.OUTLINE)
|
||||
self.outlineView.setTreeFocus()
|
||||
return
|
||||
|
||||
@@ -29,9 +29,7 @@ from PyQt5.QtWidgets import QAction, QApplication, QMenu
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.constants import nwKeyWords, nwUnicode
|
||||
from novelwriter.dialogs.editlabel import GuiEditLabel
|
||||
from novelwriter.enum import (
|
||||
nwDocAction, nwDocInsert, nwItemClass, nwItemLayout, nwTrinary, nwWidget
|
||||
)
|
||||
from novelwriter.enum import nwDocAction, nwDocInsert, nwItemClass, nwItemLayout, nwTrinary
|
||||
from novelwriter.gui.doceditor import GuiDocEditor
|
||||
from novelwriter.text.counting import standardCounter
|
||||
from novelwriter.types import (
|
||||
@@ -1678,7 +1676,7 @@ def testGuiEditor_Completer(qtbot, nwGUI, projPath, mockRnd):
|
||||
completer = docEditor._completer
|
||||
|
||||
# Create Scene
|
||||
nwGUI._switchFocus(nwWidget.EDITOR)
|
||||
nwGUI.docEditor.setFocus()
|
||||
for c in "### Scene One":
|
||||
qtbot.keyClick(docEditor, c, delay=KEY_DELAY)
|
||||
qtbot.keyClick(docEditor, Qt.Key_Return, delay=KEY_DELAY)
|
||||
|
||||
@@ -32,7 +32,7 @@ from PyQt5.QtWidgets import QInputDialog, QMenu
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.dialogs.editlabel import GuiEditLabel
|
||||
from novelwriter.enum import nwItemType, nwView, nwWidget
|
||||
from novelwriter.enum import nwFocus, nwItemType, nwView
|
||||
from novelwriter.gui.doceditor import GuiDocEditor
|
||||
from novelwriter.gui.noveltree import GuiNovelView
|
||||
from novelwriter.gui.outline import GuiOutlineView
|
||||
@@ -113,7 +113,7 @@ def testGuiMain_ProjectTreeItems(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
||||
|
||||
# Project Tree has focus
|
||||
nwGUI._changeView(nwView.PROJECT)
|
||||
nwGUI._switchFocus(nwWidget.TREE)
|
||||
nwGUI._switchFocus(nwFocus.TREE)
|
||||
nwGUI.projStack.setCurrentIndex(0)
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(GuiProjectTree, "hasFocus", lambda *a: True)
|
||||
@@ -137,7 +137,7 @@ def testGuiMain_ProjectTreeItems(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
||||
|
||||
# Project Outline has focus
|
||||
nwGUI._changeView(nwView.OUTLINE)
|
||||
nwGUI._switchFocus(nwWidget.OUTLINE)
|
||||
nwGUI._switchFocus(nwFocus.OUTLINE)
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(GuiOutlineView, "treeHasFocus", lambda *a: True)
|
||||
assert nwGUI.docEditor.docHandle is None
|
||||
@@ -230,7 +230,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd):
|
||||
CONFIG.autoScroll = True
|
||||
|
||||
# Add a Character File
|
||||
nwGUI._switchFocus(nwWidget.TREE)
|
||||
nwGUI._switchFocus(nwFocus.TREE)
|
||||
nwGUI.projView.projTree.clearSelection()
|
||||
nwGUI.projView.projTree._getTreeItem(C.hCharRoot).setSelected(True)
|
||||
nwGUI.projView.projTree.newTreeItem(nwItemType.FILE, None, isNote=True)
|
||||
@@ -250,7 +250,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd):
|
||||
docEditor._qDocument.syntaxHighlighter.initHighlighter()
|
||||
|
||||
# Type something into the document
|
||||
nwGUI._switchFocus(nwWidget.EDITOR)
|
||||
nwGUI.docEditor.setFocus()
|
||||
qtbot.keyClick(docEditor, "a", modifier=Qt.ControlModifier, delay=KEY_DELAY)
|
||||
for c in "# Jane Doe":
|
||||
qtbot.keyClick(docEditor, c, delay=KEY_DELAY)
|
||||
@@ -265,14 +265,14 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd):
|
||||
qtbot.keyClick(docEditor, Qt.Key_Return, delay=KEY_DELAY)
|
||||
|
||||
# Add a Plot File
|
||||
nwGUI._switchFocus(nwWidget.TREE)
|
||||
nwGUI._switchFocus(nwFocus.TREE)
|
||||
nwGUI.projView.projTree.clearSelection()
|
||||
nwGUI.projView.projTree._getTreeItem(C.hPlotRoot).setSelected(True)
|
||||
nwGUI.projView.projTree.newTreeItem(nwItemType.FILE, None, isNote=True)
|
||||
nwGUI.openSelectedItem()
|
||||
|
||||
# Type something into the document
|
||||
nwGUI._switchFocus(nwWidget.EDITOR)
|
||||
nwGUI.docEditor.setFocus()
|
||||
qtbot.keyClick(docEditor, "a", modifier=Qt.ControlModifier, delay=KEY_DELAY)
|
||||
for c in "# Main Plot":
|
||||
qtbot.keyClick(docEditor, c, delay=KEY_DELAY)
|
||||
@@ -287,7 +287,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd):
|
||||
qtbot.keyClick(docEditor, Qt.Key_Return, delay=KEY_DELAY)
|
||||
|
||||
# Add a World File
|
||||
nwGUI._switchFocus(nwWidget.TREE)
|
||||
nwGUI._switchFocus(nwFocus.TREE)
|
||||
nwGUI.projView.projTree.clearSelection()
|
||||
nwGUI.projView.projTree._getTreeItem(C.hWorldRoot).setSelected(True)
|
||||
nwGUI.projView.projTree.newTreeItem(nwItemType.FILE, None, isNote=True)
|
||||
@@ -299,7 +299,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd):
|
||||
docEditor.replaceText("")
|
||||
|
||||
# Type something into the document
|
||||
nwGUI._switchFocus(nwWidget.EDITOR)
|
||||
nwGUI.docEditor.setFocus()
|
||||
qtbot.keyClick(docEditor, "a", modifier=Qt.ControlModifier, delay=KEY_DELAY)
|
||||
for c in "# Main Location":
|
||||
qtbot.keyClick(docEditor, c, delay=KEY_DELAY)
|
||||
@@ -318,7 +318,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd):
|
||||
nwGUI._autoSaveProject()
|
||||
|
||||
# Select the 'New Scene' file
|
||||
nwGUI._switchFocus(nwWidget.TREE)
|
||||
nwGUI._switchFocus(nwFocus.TREE)
|
||||
nwGUI.projView.projTree.clearSelection()
|
||||
nwGUI.projView.projTree._getTreeItem(C.hNovelRoot).setExpanded(True)
|
||||
nwGUI.projView.projTree._getTreeItem(C.hChapterDir).setExpanded(True)
|
||||
@@ -326,7 +326,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd):
|
||||
nwGUI.openSelectedItem()
|
||||
|
||||
# Type something into the document
|
||||
nwGUI._switchFocus(nwWidget.EDITOR)
|
||||
nwGUI.docEditor.setFocus()
|
||||
qtbot.keyClick(docEditor, "a", modifier=Qt.ControlModifier, delay=KEY_DELAY)
|
||||
for c in "# Novel":
|
||||
qtbot.keyClick(docEditor, c, delay=KEY_DELAY)
|
||||
@@ -535,7 +535,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd):
|
||||
nwGUI.rebuildIndex()
|
||||
|
||||
# Open and view the edited document
|
||||
nwGUI._switchFocus(nwWidget.VIEWER)
|
||||
nwGUI.docViewer.setFocus()
|
||||
assert nwGUI.openDocument(C.hSceneDoc)
|
||||
assert nwGUI.viewDocument(C.hSceneDoc)
|
||||
assert nwGUI.saveProject()
|
||||
|
||||
@@ -30,7 +30,7 @@ from PyQt5.QtWidgets import QInputDialog, QToolTip
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.dialogs.editlabel import GuiEditLabel
|
||||
from novelwriter.enum import nwItemType, nwWidget
|
||||
from novelwriter.enum import nwFocus, nwItemType
|
||||
from novelwriter.gui.noveltree import GuiNovelTree, NovelTreeColumn
|
||||
from novelwriter.types import QtMouseLeft
|
||||
|
||||
@@ -44,7 +44,7 @@ def testGuiNovelTree_TreeItems(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
||||
|
||||
buildTestProject(nwGUI, projPath)
|
||||
|
||||
nwGUI._switchFocus(nwWidget.TREE)
|
||||
nwGUI._switchFocus(nwFocus.TREE)
|
||||
nwGUI.projView.projTree.clearSelection()
|
||||
nwGUI.projView.projTree._getTreeItem(C.hCharRoot).setSelected(True)
|
||||
nwGUI.projView.projTree.newTreeItem(nwItemType.FILE)
|
||||
|
||||
@@ -34,7 +34,7 @@ from novelwriter.core.project import NWProject
|
||||
from novelwriter.dialogs.docmerge import GuiDocMerge
|
||||
from novelwriter.dialogs.docsplit import GuiDocSplit
|
||||
from novelwriter.dialogs.editlabel import GuiEditLabel
|
||||
from novelwriter.enum import nwItemClass, nwItemLayout, nwItemType, nwWidget
|
||||
from novelwriter.enum import nwFocus, nwItemClass, nwItemLayout, nwItemType
|
||||
from novelwriter.gui.projtree import GuiProjectTree, GuiProjectView, _TreeContextMenu
|
||||
from novelwriter.guimain import GuiMain
|
||||
from novelwriter.types import QtAccepted, QtModNone, QtMouseLeft, QtMouseMiddle, QtRejected
|
||||
@@ -1111,7 +1111,7 @@ def testGuiProjTree_ContextMenu(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
||||
# Create a project
|
||||
buildTestProject(nwGUI, projPath)
|
||||
nwGUI.openProject(projPath)
|
||||
nwGUI._switchFocus(nwWidget.TREE)
|
||||
nwGUI._switchFocus(nwFocus.TREE)
|
||||
|
||||
# Handles for new objects
|
||||
hCharNote = "0000000000011"
|
||||
@@ -1408,7 +1408,7 @@ def testGuiProjTree_Templates(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
||||
# Create a project
|
||||
buildTestProject(nwGUI, projPath)
|
||||
nwGUI.openProject(projPath)
|
||||
nwGUI._switchFocus(nwWidget.TREE)
|
||||
nwGUI._switchFocus(nwFocus.TREE)
|
||||
nwGUI.show()
|
||||
|
||||
project = SHARED.project
|
||||
|
||||
Reference in New Issue
Block a user