Connect the new viewer panel and add icon for it

This commit is contained in:
Veronica Berglyd Olsen
2023-11-14 22:41:39 +01:00
parent 1d89e4935f
commit 4d7ef63e83
12 changed files with 184 additions and 275 deletions
@@ -59,6 +59,7 @@ maximise = typ_arrow-maximise.svg
menu = typ_th-dot-menu.svg
minimise = typ_arrow-minimise.svg
noncheckable = mixed_input-none.svg
panel = nw_panel.svg
proj_chapter = mixed_document-chapter.svg
proj_details = typ_th-list-grey.svg
proj_document = typ_document-text.svg
@@ -68,7 +69,6 @@ proj_scene = mixed_document-scene.svg
proj_section = mixed_document-section.svg
proj_stats = typ_chart-bar-grey.svg
proj_title = mixed_document-title.svg
reference = typ_at.svg
refresh = typ_refresh.svg
remove = typ_minus.svg
revert = typ_refresh-flipped.svg
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m17.853 2.0017c-0.14248-0.00428-0.28548-1.936e-4 -0.42925 0.01171h-11.135c-2.3531-0.068148-4.4276 2.1102-4.2808 4.4518 0.00689 3.8473-0.014486 7.6959 0.00976 11.542 0.12963 2.1674 2.0751 4.0505 4.2711 3.9912 3.8794-0.0037 7.7592 0.0071 11.639-0.0059 2.3157-0.05864 4.2507-2.2581 4.0603-4.5591-0.0037-3.7862 0.0071-7.5728-0.0059-11.359-0.054966-2.1716-1.9914-4.0089-4.1286-4.0732zm-11.533 2.8514c0.10262-0.00515 0.20595 1.374e-4 0.30828 0.015613 2.2719-0.00131 4.5437 0.0026 6.8153-0.00195 1.5163 0.01818 3.0369-0.036922 4.5501 0.029275 0.83106 0.14317 1.246 1.0195 1.1395 1.7956-0.0023 1.7714-9.95e-4 3.543 0 5.3144h-14.271c-9.495e-4 -1.9468-0.0019-3.8929 0.00585-5.8394 0.049778-0.75434 0.73334-1.2775 1.4517-1.3135z" fill="#848484" stroke-width=".99912"/>
</svg>

After

Width:  |  Height:  |  Size: 912 B

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m12 2c-5.5138 0-10 4.4862-10 10s4.4862 10 10 10c2.02 0 3.965-0.59875 5.6238-1.73 0.57-0.39 0.7175-1.1675 0.32875-1.7375-0.38875-0.57125-1.165-0.715-1.7375-0.32875-1.2425 0.84875-2.7 1.2962-4.215 1.2962-4.1362 0-7.5-3.3638-7.5-7.5s3.3638-7.5 7.5-7.5 7.5 3.3638 7.5 7.5v0.625c0 0.69-0.56 1.25-1.25 1.25s-1.25-0.56-1.25-1.25v-3.75c0-0.69125-0.55875-1.25-1.25-1.25-0.55125 0-1.0062 0.3625-1.1725 0.86-0.725-0.53375-1.6112-0.86-2.5775-0.86-2.4125 0-4.375 1.9625-4.375 4.375s1.9625 4.375 4.375 4.375c1.3062 0 2.4688-0.5875 3.27-1.4988 0.685 0.90375 1.76 1.4988 2.98 1.4988 2.0675 0 3.75-1.6825 3.75-3.75v-0.625c0-5.5138-4.4862-10-10-10zm0 11.875c-1.0338 0-1.875-0.84125-1.875-1.875s0.84125-1.875 1.875-1.875 1.875 0.84125 1.875 1.875-0.84125 1.875-1.875 1.875z" fill="#69c" stroke-width="1.25"/>
</svg>

Before

Width:  |  Height:  |  Size: 944 B

@@ -59,6 +59,7 @@ maximise = typ_arrow-maximise.svg
menu = typ_th-dot-menu.svg
minimise = typ_arrow-minimise.svg
noncheckable = mixed_input-none.svg
panel = nw_panel.svg
proj_chapter = mixed_document-chapter.svg
proj_details = typ_th-list-grey.svg
proj_document = typ_document-text.svg
@@ -68,7 +69,6 @@ proj_scene = mixed_document-scene.svg
proj_section = mixed_document-section.svg
proj_stats = typ_chart-bar-grey.svg
proj_title = mixed_document-title.svg
reference = typ_at.svg
refresh = typ_refresh.svg
remove = typ_minus.svg
revert = typ_refresh-flipped.svg
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m17.853 2.0017c-0.14248-0.00428-0.28548-1.936e-4 -0.42925 0.01171h-11.135c-2.3531-0.068148-4.4276 2.1102-4.2808 4.4518 0.00689 3.8473-0.014486 7.6959 0.00976 11.542 0.12963 2.1674 2.0751 4.0505 4.2711 3.9912 3.8794-0.0037 7.7592 0.0071 11.639-0.0059 2.3157-0.05864 4.2507-2.2581 4.0603-4.5591-0.0037-3.7862 0.0071-7.5728-0.0059-11.359-0.054966-2.1716-1.9914-4.0089-4.1286-4.0732zm-11.533 2.8514c0.10262-0.00515 0.20595 1.374e-4 0.30828 0.015613 2.2719-0.00131 4.5437 0.0026 6.8153-0.00195 1.5163 0.01818 3.0369-0.036922 4.5501 0.029275 0.83106 0.14317 1.246 1.0195 1.1395 1.7956-0.0023 1.7714-9.95e-4 3.543 0 5.3144h-14.271c-9.495e-4 -1.9468-0.0019-3.8929 0.00585-5.8394 0.049778-0.75434 0.73334-1.2775 1.4517-1.3135z" fill-opacity=".78039" stroke-width=".99912"/>
</svg>

After

Width:  |  Height:  |  Size: 919 B

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m12 2c-5.5138 0-10 4.4862-10 10s4.4862 10 10 10c2.02 0 3.965-0.59875 5.6238-1.73 0.57-0.39 0.7175-1.1675 0.32875-1.7375-0.38875-0.57125-1.165-0.715-1.7375-0.32875-1.2425 0.84875-2.7 1.2962-4.215 1.2962-4.1362 0-7.5-3.3638-7.5-7.5s3.3638-7.5 7.5-7.5 7.5 3.3638 7.5 7.5v0.625c0 0.69-0.56 1.25-1.25 1.25s-1.25-0.56-1.25-1.25v-3.75c0-0.69125-0.55875-1.25-1.25-1.25-0.55125 0-1.0062 0.3625-1.1725 0.86-0.725-0.53375-1.6112-0.86-2.5775-0.86-2.4125 0-4.375 1.9625-4.375 4.375s1.9625 4.375 4.375 4.375c1.3062 0 2.4688-0.5875 3.27-1.4988 0.685 0.90375 1.76 1.4988 2.98 1.4988 2.0675 0 3.75-1.6825 3.75-3.75v-0.625c0-5.5138-4.4862-10-10-10zm0 11.875c-1.0338 0-1.875-0.84125-1.875-1.875s0.84125-1.875 1.875-1.875 1.875 0.84125 1.875 1.875-0.84125 1.875-1.875 1.875z" fill="#4271ae" stroke-width="1.25"/>
</svg>

Before

Width:  |  Height:  |  Size: 947 B

+4 -4
View File
@@ -179,9 +179,9 @@ class Config:
self.spellLanguage = "en"
# State
self.showRefPanel = True # The reference panel for the viewer is visible
self.showViewerPanel = True # The panel for the viewer is visible
self.showEditToolBar = False # The document editor toolbar visibility
self.useShortcodes = False # Use shorcodes for basic formatting
self.useShortcodes = False # Use shortcodes for basic formatting
self.viewComments = True # Comments are shown in the viewer
self.viewSynopsis = True # Synopsis is shown in the viewer
@@ -602,7 +602,7 @@ class Config:
# State
sec = "State"
self.showRefPanel = conf.rdBool(sec, "showrefpanel", self.showRefPanel)
self.showViewerPanel = conf.rdBool(sec, "showviewerpanel", self.showViewerPanel)
self.showEditToolBar = conf.rdBool(sec, "showedittoolbar", self.showEditToolBar)
self.useShortcodes = conf.rdBool(sec, "useshortcodes", self.useShortcodes)
self.viewComments = conf.rdBool(sec, "viewcomments", self.viewComments)
@@ -727,7 +727,7 @@ class Config:
}
conf["State"] = {
"showrefpanel": str(self.showRefPanel),
"showviewerpanel": str(self.showViewerPanel),
"showedittoolbar": str(self.showEditToolBar),
"useshortcodes": str(self.useShortcodes),
"viewcomments": str(self.viewComments),
+16 -1
View File
@@ -153,6 +153,21 @@ class nwKeyWords:
# END Class nwKeyWords
class nwLists:
USER_CLASSES = [
nwItemClass.CHARACTER,
nwItemClass.PLOT,
nwItemClass.WORLD,
nwItemClass.TIMELINE,
nwItemClass.OBJECT,
nwItemClass.ENTITY,
nwItemClass.CUSTOM,
]
# END Class nwLists
class nwLabels:
CLASS_NAME = {
@@ -221,8 +236,8 @@ class nwLabels:
nwOutline.FOCUS: QT_TRANSLATE_NOOP("Constant", "Focus"),
nwOutline.CHAR: KEY_NAME[nwKeyWords.CHAR_KEY],
nwOutline.PLOT: KEY_NAME[nwKeyWords.PLOT_KEY],
nwOutline.TIME: KEY_NAME[nwKeyWords.TIME_KEY],
nwOutline.WORLD: KEY_NAME[nwKeyWords.WORLD_KEY],
nwOutline.TIME: KEY_NAME[nwKeyWords.TIME_KEY],
nwOutline.OBJECT: KEY_NAME[nwKeyWords.OBJECT_KEY],
nwOutline.ENTITY: KEY_NAME[nwKeyWords.ENTITY_KEY],
nwOutline.CUSTOM: KEY_NAME[nwKeyWords.CUSTOM_KEY],
+59 -225
View File
@@ -4,7 +4,6 @@ novelWriter GUI Document Viewer
File History:
Created: 2019-05-10 [0.0.1] GuiDocViewer
Created: 2019-10-31 [0.3.2] GuiDocViewDetails
Created: 2020-04-25 [0.4.5] GuiDocViewHeader
Created: 2020-06-09 [0.8] GuiDocViewFooter
Created: 2020-09-08 [1.0b1] GuiDocViewHistory
@@ -38,8 +37,8 @@ from PyQt5.QtGui import (
QTextOption
)
from PyQt5.QtWidgets import (
QAction, qApp, QFrame, QHBoxLayout, QLabel, QMenu, QScrollArea,
QTextBrowser, QToolButton, QWidget
QAction, qApp, QFrame, QHBoxLayout, QLabel, QMenu, QTextBrowser,
QToolButton, QWidget
)
from novelwriter import CONFIG, SHARED
@@ -58,6 +57,7 @@ logger = logging.getLogger(__name__)
class GuiDocViewer(QTextBrowser):
loadDocumentTagRequest = pyqtSignal(str, Enum)
togglePanelVisibility = pyqtSignal()
def __init__(self, mainGui: GuiMain) -> None:
super().__init__(parent=mainGui)
@@ -242,7 +242,7 @@ class GuiDocViewer(QTextBrowser):
self.updateDocMargins()
# Make sure the main GUI knows we changed the content
self.mainGui.viewMeta.refreshReferences(tHandle)
# self.mainGui.viewMeta.refreshReferences(tHandle)
# Since we change the content while it may still be rendering, we mark
# the document dirty again to make sure it's re-rendered properly.
@@ -342,7 +342,7 @@ class GuiDocViewer(QTextBrowser):
@pyqtSlot(str)
def updateDocInfo(self, tHandle: str) -> None:
"""Update the header titlebar if needed."""
"""Update the header title bar if needed."""
if tHandle == self._docHandle:
self.docHeader.setTitleFromHandle(self._docHandle)
self.updateDocMargins()
@@ -530,20 +530,16 @@ class GuiDocViewer(QTextBrowser):
class GuiDocViewHistory:
def __init__(self, docViewer):
def __init__(self, docViewer: GuiDocViewer) -> None:
self.docViewer = docViewer
self._navHistory = []
self._posHistory = []
self._currPos = -1
self._prevPos = -1
return
def clear(self):
"""Clear the view history.
"""
def clear(self) -> None:
"""Clear the view history."""
logger.debug("View history cleared")
self._navHistory = []
self._posHistory = []
@@ -551,7 +547,7 @@ class GuiDocViewHistory:
self._prevPos = -1
return
def append(self, tHandle):
def append(self, tHandle: str) -> bool:
"""Append a document handle and its scroll bar position to the
history, but only if the document is different than the current
active entry. Any further entries are truncated.
@@ -577,74 +573,61 @@ class GuiDocViewHistory:
return True
def forward(self):
"""Navigate to the next entry in the view history.
"""
def forward(self) -> None:
"""Navigate to the next entry in the view history."""
newPos = self._currPos + 1
if newPos < len(self._navHistory):
logger.debug("Move forward in view history")
self._prevPos = self._currPos
self._updateScrollBar()
self.docViewer.loadText(self._navHistory[newPos], updateHistory=False)
self.docViewer.setScrollPosition(self._posHistory[newPos])
self._currPos = newPos
self._updateNavButtons()
self._dumpHistory()
return
def backward(self):
"""Navigate to the previous entry in the view history.
"""
def backward(self) -> None:
"""Navigate to the previous entry in the view history."""
newPos = self._currPos - 1
if newPos >= 0:
logger.debug("Move backward in view history")
self._prevPos = self._currPos
self._updateScrollBar()
self.docViewer.loadText(self._navHistory[newPos], updateHistory=False)
self.docViewer.setScrollPosition(self._posHistory[newPos])
self._currPos = newPos
self._updateNavButtons()
self._dumpHistory()
return
##
# Internal Functions
##
def _updateScrollBar(self):
"""Update the scrollbar position of the previous entry.
"""
def _updateScrollBar(self) -> None:
"""Update the scrollbar position of the previous entry."""
if self._prevPos >= 0 and self._prevPos < len(self._posHistory):
self._posHistory[self._prevPos] = self.docViewer.scrollPosition
return
def _updateNavButtons(self):
"""Update the navigation buttons in the document header.
"""
def _updateNavButtons(self) -> None:
"""Update the navigation buttons in the document header."""
self.docViewer.docHeader.updateNavButtons(0, len(self._navHistory) - 1, self._currPos)
return
def _truncateHistory(self, atPos):
def _truncateHistory(self, atPos: int) -> None:
"""Truncate the navigation history to the given position. Also
enforces a maximum length of the navigation history to 20.
"""
nSkip = 1 if atPos > 19 else 0
self._navHistory = self._navHistory[nSkip:atPos + 1]
self._posHistory = self._posHistory[nSkip:atPos + 1]
self._currPos -= nSkip
self._prevPos -= nSkip
return
def _dumpHistory(self):
def _dumpHistory(self) -> None:
"""Debug function to dump history to the logger. Since it is a
for loop, it is skipped entirely if log level isn't DEBUG.
"""
@@ -667,7 +650,7 @@ class GuiDocViewHistory:
class GuiDocViewHeader(QWidget):
def __init__(self, docViewer):
def __init__(self, docViewer: GuiDocViewer) -> None:
super().__init__(parent=docViewer)
logger.debug("Create: GuiDocViewHeader")
@@ -763,9 +746,8 @@ class GuiDocViewHeader(QWidget):
# Methods
##
def updateTheme(self):
"""Update theme elements.
"""
def updateTheme(self) -> None:
"""Update theme elements."""
self.backButton.setIcon(SHARED.theme.getIcon("backward"))
self.forwardButton.setIcon(SHARED.theme.getIcon("forward"))
self.refreshButton.setIcon(SHARED.theme.getIcon("refresh"))
@@ -785,7 +767,7 @@ class GuiDocViewHeader(QWidget):
return
def matchColours(self):
def matchColours(self) -> None:
"""Update the colours of the widget to match those of the syntax
theme rather than the main GUI.
"""
@@ -793,13 +775,11 @@ class GuiDocViewHeader(QWidget):
thePalette.setColor(QPalette.Window, QColor(*SHARED.theme.colBack))
thePalette.setColor(QPalette.WindowText, QColor(*SHARED.theme.colText))
thePalette.setColor(QPalette.Text, QColor(*SHARED.theme.colText))
self.setPalette(thePalette)
self.theTitle.setPalette(thePalette)
return
def setTitleFromHandle(self, tHandle):
def setTitleFromHandle(self, tHandle: str | None) -> bool:
"""Sets the document title from the handle, or alternatively,
set the whole document path.
"""
@@ -835,28 +815,25 @@ class GuiDocViewHeader(QWidget):
return True
def updateNavButtons(self, firstIdx, lastIdx, currIdx):
"""Enable and disable nav buttons based on index in history.
"""
def updateNavButtons(self, firstIdx: int, lastIdx: int, currIdx: int) -> None:
"""Enable and disable nav buttons based on index in history."""
self.backButton.setEnabled(currIdx > firstIdx)
self.forwardButton.setEnabled(currIdx < lastIdx)
return
##
# Slots
# Private Slots
##
@pyqtSlot()
def _closeDocument(self):
"""Trigger the close editor/viewer on the main window.
"""
def _closeDocument(self) -> None:
"""Trigger the close editor/viewer on the main window."""
self.mainGui.closeDocViewer()
return
@pyqtSlot()
def _refreshDocument(self):
"""Reload the content of the document.
"""
def _refreshDocument(self) -> None:
"""Reload the content of the document."""
if self.docViewer.docHandle == self.mainGui.docEditor.docHandle:
self.mainGui.saveDocument()
self.docViewer.reloadText()
@@ -866,7 +843,7 @@ class GuiDocViewHeader(QWidget):
# Events
##
def mousePressEvent(self, theEvent):
def mousePressEvent(self, event: QMouseEvent) -> None:
"""Capture a click on the title and ensure that the item is
selected in the project tree.
"""
@@ -883,14 +860,13 @@ class GuiDocViewHeader(QWidget):
class GuiDocViewFooter(QWidget):
def __init__(self, docViewer):
def __init__(self, docViewer: GuiDocViewer) -> None:
super().__init__(parent=docViewer)
logger.debug("Create: GuiDocViewFooter")
self.docViewer = docViewer
self.mainGui = docViewer.mainGui
self.viewMeta = docViewer.mainGui.viewMeta
# Internal Variables
self._docHandle = None
@@ -908,19 +884,8 @@ class GuiDocViewFooter(QWidget):
self.showHide.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.showHide.setIconSize(QSize(fPx, fPx))
self.showHide.setFixedSize(QSize(fPx, fPx))
self.showHide.clicked.connect(self._doShowHide)
self.showHide.setToolTip(self.tr("Show/hide the references panel"))
# Sticky Button
self.stickyRefs = QToolButton(self)
self.stickyRefs.setCheckable(True)
self.stickyRefs.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.stickyRefs.setIconSize(QSize(fPx, fPx))
self.stickyRefs.setFixedSize(QSize(fPx, fPx))
self.stickyRefs.toggled.connect(self._doToggleSticky)
self.stickyRefs.setToolTip(self.tr(
"Activate to freeze the content of the references panel when changing document"
))
self.showHide.clicked.connect(lambda: self.docViewer.togglePanelVisibility.emit())
self.showHide.setToolTip(self.tr("Show/Hide Viewer Panel"))
# Show Comments
self.showComments = QToolButton(self)
@@ -930,7 +895,7 @@ class GuiDocViewFooter(QWidget):
self.showComments.setIconSize(QSize(fPx, fPx))
self.showComments.setFixedSize(QSize(fPx, fPx))
self.showComments.toggled.connect(self._doToggleComments)
self.showComments.setToolTip(self.tr("Show comments"))
self.showComments.setToolTip(self.tr("Show Comments"))
# Show Synopsis
self.showSynopsis = QToolButton(self)
@@ -940,27 +905,9 @@ class GuiDocViewFooter(QWidget):
self.showSynopsis.setIconSize(QSize(fPx, fPx))
self.showSynopsis.setFixedSize(QSize(fPx, fPx))
self.showSynopsis.toggled.connect(self._doToggleSynopsis)
self.showSynopsis.setToolTip(self.tr("Show synopsis comments"))
self.showSynopsis.setToolTip(self.tr("Show Synopsis Comments"))
# Labels
self.lblRefs = QLabel(self.tr("References"))
self.lblRefs.setBuddy(self.showHide)
self.lblRefs.setIndent(0)
self.lblRefs.setMargin(0)
self.lblRefs.setContentsMargins(0, 0, 0, 0)
self.lblRefs.setAutoFillBackground(True)
self.lblRefs.setFixedHeight(fPx)
self.lblRefs.setAlignment(Qt.AlignLeft | Qt.AlignTop)
self.lblSticky = QLabel(self.tr("Sticky"))
self.lblSticky.setBuddy(self.stickyRefs)
self.lblSticky.setIndent(0)
self.lblSticky.setMargin(0)
self.lblSticky.setContentsMargins(0, 0, 0, 0)
self.lblSticky.setAutoFillBackground(True)
self.lblSticky.setFixedHeight(fPx)
self.lblSticky.setAlignment(Qt.AlignLeft | Qt.AlignTop)
self.lblComments = QLabel(self.tr("Comments"))
self.lblComments.setBuddy(self.showComments)
self.lblComments.setIndent(0)
@@ -981,8 +928,6 @@ class GuiDocViewFooter(QWidget):
lblFont = self.font()
lblFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)
self.lblRefs.setFont(lblFont)
self.lblSticky.setFont(lblFont)
self.lblComments.setFont(lblFont)
self.lblSynopsis.setFont(lblFont)
@@ -990,10 +935,6 @@ class GuiDocViewFooter(QWidget):
self.outerBox = QHBoxLayout()
self.outerBox.setSpacing(bSp)
self.outerBox.addWidget(self.showHide, 0)
self.outerBox.addWidget(self.lblRefs, 0)
self.outerBox.addSpacing(hSp)
self.outerBox.addWidget(self.stickyRefs, 0)
self.outerBox.addWidget(self.lblSticky, 0)
self.outerBox.addStretch(1)
self.outerBox.addWidget(self.showComments, 0)
self.outerBox.addWidget(self.lblComments, 0)
@@ -1024,23 +965,19 @@ class GuiDocViewFooter(QWidget):
"""Update theme elements."""
# Icons
fPx = int(0.9*SHARED.theme.fontPixelSize)
stickyIcon = SHARED.theme.getToggleIcon("sticky", (fPx, fPx))
bulletIcon = SHARED.theme.getToggleIcon("bullet", (fPx, fPx))
self.showHide.setIcon(SHARED.theme.getIcon("reference"))
self.stickyRefs.setIcon(stickyIcon)
self.showHide.setIcon(SHARED.theme.getIcon("panel"))
self.showComments.setIcon(bulletIcon)
self.showSynopsis.setIcon(bulletIcon)
# StyleSheets
buttonStyle = (
"QToolButton {{border: none; background: transparent;}} "
"QToolButton:hover {{border: none; background: rgba({0},{1},{2},0.2);}}"
).format(*SHARED.theme.colText)
self.showHide.setStyleSheet(buttonStyle)
self.stickyRefs.setStyleSheet(buttonStyle)
self.showComments.setStyleSheet(buttonStyle)
self.showSynopsis.setStyleSheet(buttonStyle)
@@ -1048,138 +985,35 @@ class GuiDocViewFooter(QWidget):
return
def matchColours(self):
def matchColours(self) -> None:
"""Update the colours of the widget to match those of the syntax
theme rather than the main GUI.
"""
thePalette = QPalette()
thePalette.setColor(QPalette.Window, QColor(*SHARED.theme.colBack))
thePalette.setColor(QPalette.WindowText, QColor(*SHARED.theme.colText))
thePalette.setColor(QPalette.Text, QColor(*SHARED.theme.colText))
self.setPalette(thePalette)
self.lblRefs.setPalette(thePalette)
self.lblSticky.setPalette(thePalette)
self.lblComments.setPalette(thePalette)
self.lblSynopsis.setPalette(thePalette)
return
##
# Slots
##
@pyqtSlot()
def _doShowHide(self):
"""Toggle the expand/collapse of the panel.
"""
isVisible = self.viewMeta.isVisible()
self.viewMeta.setVisible(not isVisible)
return
@pyqtSlot(bool)
def _doToggleSticky(self, theState):
"""Toggle the sticky flag for the reference panel.
"""
logger.debug("Reference sticky is %s", str(theState))
self.docViewer.stickyRef = theState
if not theState and self.docViewer.docHandle is not None:
self.viewMeta.refreshReferences(self.docViewer.docHandle)
return
@pyqtSlot(bool)
def _doToggleComments(self, theState):
"""Toggle the view comment button and reload the document.
"""
CONFIG.viewComments = theState
self.docViewer.reloadText()
return
@pyqtSlot(bool)
def _doToggleSynopsis(self, theState):
"""Toggle the view synopsis button and reload the document.
"""
CONFIG.viewSynopsis = theState
self.docViewer.reloadText()
return
# END Class GuiDocViewFooter
# =============================================================================================== #
# The Document Back-Reference Panel
# Placed in a separate QSplitter position in the main GUI window
# =============================================================================================== #
class GuiDocViewDetails(QScrollArea):
def __init__(self, mainGui):
super().__init__(parent=mainGui)
logger.debug("Create: GuiDocViewDetails")
self.mainGui = mainGui
self.refList = QLabel("")
self.refList.setWordWrap(True)
self.refList.setAlignment(Qt.AlignTop)
self.refList.setScaledContents(True)
self.refList.linkActivated.connect(self._linkClicked)
self.linkStyle = "style='color: rgb({0},{1},{2})'".format(*SHARED.theme.colLink)
# Assemble
self.outerWidget = QWidget()
self.outerBox = QHBoxLayout()
self.outerBox.addWidget(self.refList, 1)
self.outerWidget.setLayout(self.outerBox)
self.setWidget(self.outerWidget)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.setWidgetResizable(True)
self.setMinimumHeight(CONFIG.pxInt(50))
self.setFrameStyle(QFrame.NoFrame)
logger.debug("Ready: GuiDocViewDetails")
return
def refreshReferences(self, tHandle):
"""Update the current list of document references from the
project index.
"""
if self.mainGui.docViewer.stickyRef:
return
theRefs = SHARED.project.index.getBackReferenceList(tHandle)
theList = []
for tHandle in theRefs:
tItem = SHARED.project.tree[tHandle]
if tItem is not None:
theList.append("<a href='%s#%s' %s>%s</a>" % (
tHandle, theRefs[tHandle], self.linkStyle, tItem.itemName
))
self.refList.setText(", ".join(theList))
palette = QPalette()
palette.setColor(QPalette.Window, QColor(*SHARED.theme.colBack))
palette.setColor(QPalette.WindowText, QColor(*SHARED.theme.colText))
palette.setColor(QPalette.Text, QColor(*SHARED.theme.colText))
self.setPalette(palette)
self.lblComments.setPalette(palette)
self.lblSynopsis.setPalette(palette)
return
##
# Private Slots
##
@pyqtSlot(str)
def _linkClicked(self, theLink):
"""Capture the link-click and forward it to the document viewer
class for handling.
"""
logger.debug("Clicked link: '%s'", theLink)
if len(theLink) >= 13:
tHandle = theLink[:13]
tAnchor = theLink[13:] or None
self.mainGui.viewDocument(tHandle, tAnchor)
@pyqtSlot(bool)
def _doToggleComments(self, state: bool) -> None:
"""Toggle the view comment button and reload the document."""
CONFIG.viewComments = state
self.docViewer.reloadText()
return
# END Class GuiDocViewDetails
@pyqtSlot(bool)
def _doToggleSynopsis(self, state: bool) -> None:
"""Toggle the view synopsis button and reload the document."""
CONFIG.viewSynopsis = state
self.docViewer.reloadText()
return
# END Class GuiDocViewFooter
+61 -11
View File
@@ -3,7 +3,7 @@ novelWriter GUI Document Viewer Panel
=======================================
File History:
Created: 2023-11-09 [2.2a1] GuiDocViewerPanel
Created: 2023-11-14 [2.2rc1] GuiDocViewerPanel
This file is a part of novelWriter
Copyright 20182023, Veronica Berglyd Olsen
@@ -25,40 +25,90 @@ from __future__ import annotations
import logging
from PyQt5.QtWidgets import QVBoxLayout, QWidget
from PyQt5.QtWidgets import QTabWidget, QVBoxLayout, QWidget
from novelwriter.gui.docviewer import GuiDocViewer
from novelwriter import CONFIG
from novelwriter.constants import nwLabels, nwLists, trConst
logger = logging.getLogger(__name__)
class GuiDocViewerPanel(QWidget):
def __init__(self, docViewer: GuiDocViewer) -> None:
super().__init__(parent=docViewer)
def __init__(self, parent: QWidget) -> None:
super().__init__(parent=parent)
logger.debug("Create: GuiDocViewerPanel")
self.panelHeader = GuiDocViewerPanelHeader(self)
self.tabBackRefs = _ViewPanelBackRefs(self)
self.mainTabs = QTabWidget(self)
self.mainTabs.addTab(self.tabBackRefs, self.tr("Back References"))
self.kwTabs = {}
for itemClass in nwLists.USER_CLASSES:
self.kwTabs[itemClass] = _ViewPanelKeyWords(self)
self.mainTabs.addTab(self.kwTabs[itemClass], trConst(nwLabels.CLASS_NAME[itemClass]))
# Assemble
self.outerBox = QVBoxLayout()
self.outerBox.addWidget(self.panelHeader)
self.outerBox.addWidget(self.mainTabs)
self.outerBox.setContentsMargins(0, 0, 0, 0)
self.setLayout(self.outerBox)
self.updateTheme()
logger.debug("Ready: GuiDocViewerPanel")
return
def updateTheme(self) -> None:
"""Update theme elements."""
vPx = CONFIG.pxInt(4)
lPx = CONFIG.pxInt(2)
rPx = CONFIG.pxInt(14)
hCol = self.palette().highlight().color()
styleSheet = (
"QTabWidget QTabBar::tab {"
f"border: 0; padding: {vPx}px {rPx}px {vPx}px {lPx}px;"
"} "
"QTabWidget QTabBar::tab:selected {"
f"color: rgb({hCol.red()}, {hCol.green()}, {hCol.blue()});"
"} "
)
self.mainTabs.setStyleSheet(styleSheet)
return
# END Class GuiDocViewerPanel
class GuiDocViewerPanelHeader(QWidget):
class _ViewPanelBackRefs(QWidget):
def __init__(self, docViewerPanel: GuiDocViewerPanel) -> None:
super().__init__(parent=docViewerPanel)
def __init__(self, parent: QWidget) -> None:
super().__init__(parent=parent)
return
# END Class GuiDocViewerPanelHeader
def refreshContent(self):
""""""
# theRefs = SHARED.project.index.getBackReferenceList(tHandle)
# theList = []
# for tHandle in theRefs:
# tItem = SHARED.project.tree[tHandle]
# if tItem is not None:
# theList.append("<a href='%s#%s' %s>%s</a>" % (
# tHandle, theRefs[tHandle], self.linkStyle, tItem.itemName
# ))
return
# END Class _ViewPanelBackRefs
class _ViewPanelKeyWords(QWidget):
def __init__(self, parent: QWidget) -> None:
super().__init__(parent=parent)
return
# END Class _ViewPanelRefs
+2 -2
View File
@@ -464,8 +464,8 @@ class GuiIcons:
# General Button Icons
"add", "backward", "bookmark", "browse", "checked", "close", "cross", "down", "edit",
"export", "forward", "maximise", "menu", "minimise", "noncheckable", "reference",
"refresh", "remove", "revert", "search_replace", "search", "settings", "unchecked", "up",
"export", "forward", "maximise", "menu", "minimise", "noncheckable", "panel", "refresh",
"remove", "revert", "search_replace", "search", "settings", "unchecked", "up",
# Switches
"sticky-on", "sticky-off",
+32 -22
View File
@@ -44,10 +44,11 @@ from novelwriter.gui.outline import GuiOutlineView
from novelwriter.gui.mainmenu import GuiMainMenu
from novelwriter.gui.projtree import GuiProjectView
from novelwriter.gui.doceditor import GuiDocEditor
from novelwriter.gui.docviewer import GuiDocViewDetails, GuiDocViewer
from novelwriter.gui.docviewer import GuiDocViewer
from novelwriter.gui.noveltree import GuiNovelView
from novelwriter.gui.statusbar import GuiMainStatus
from novelwriter.gui.itemdetails import GuiItemDetails
from novelwriter.gui.docviewerpanel import GuiDocViewerPanel
from novelwriter.dialogs.about import GuiAbout
from novelwriter.dialogs.updates import GuiUpdates
from novelwriter.dialogs.projload import GuiProjectLoad
@@ -133,16 +134,16 @@ class GuiMain(QMainWindow):
hWd = CONFIG.pxInt(4)
# Main GUI Elements
self.mainStatus = GuiMainStatus(self)
self.projView = GuiProjectView(self)
self.novelView = GuiNovelView(self)
self.docEditor = GuiDocEditor(self)
self.viewMeta = GuiDocViewDetails(self)
self.docViewer = GuiDocViewer(self)
self.itemDetails = GuiItemDetails(self)
self.outlineView = GuiOutlineView(self)
self.mainMenu = GuiMainMenu(self)
self.sideBar = GuiSideBar(self)
self.mainStatus = GuiMainStatus(self)
self.projView = GuiProjectView(self)
self.novelView = GuiNovelView(self)
self.docEditor = GuiDocEditor(self)
self.docViewer = GuiDocViewer(self)
self.docViewerPanel = GuiDocViewerPanel(self)
self.itemDetails = GuiItemDetails(self)
self.outlineView = GuiOutlineView(self)
self.mainMenu = GuiMainMenu(self)
self.sideBar = GuiSideBar(self)
# Project Tree Stack
self.projStack = QStackedWidget(self)
@@ -162,7 +163,7 @@ class GuiMain(QMainWindow):
# Splitter : Document Viewer / Document Meta
self.splitView = QSplitter(Qt.Vertical, self)
self.splitView.addWidget(self.docViewer)
self.splitView.addWidget(self.viewMeta)
self.splitView.addWidget(self.docViewerPanel)
self.splitView.setHandleWidth(hWd)
self.splitView.setOpaqueResize(False)
self.splitView.setSizes(CONFIG.viewPanePos)
@@ -190,12 +191,12 @@ class GuiMain(QMainWindow):
self.mainStack.currentChanged.connect(self._mainStackChanged)
# Indices of Splitter Widgets
self.idxTree = self.splitMain.indexOf(self.treePane)
self.idxMain = self.splitMain.indexOf(self.splitDocs)
self.idxEditor = self.splitDocs.indexOf(self.docEditor)
self.idxViewer = self.splitDocs.indexOf(self.splitView)
self.idxViewDoc = self.splitView.indexOf(self.docViewer)
self.idxViewMeta = self.splitView.indexOf(self.viewMeta)
self.idxTree = self.splitMain.indexOf(self.treePane)
self.idxMain = self.splitMain.indexOf(self.splitDocs)
self.idxEditor = self.splitDocs.indexOf(self.docEditor)
self.idxViewer = self.splitDocs.indexOf(self.splitView)
self.idxViewDoc = self.splitView.indexOf(self.docViewer)
self.idxViewDocPanel = self.splitView.indexOf(self.docViewerPanel)
# Indices of Stack Widgets
self.idxEditorView = self.mainStack.indexOf(self.splitMain)
@@ -209,7 +210,7 @@ class GuiMain(QMainWindow):
self.splitDocs.setCollapsible(self.idxEditor, False)
self.splitDocs.setCollapsible(self.idxViewer, False)
self.splitView.setCollapsible(self.idxViewDoc, False)
self.splitView.setCollapsible(self.idxViewMeta, False)
self.splitView.setCollapsible(self.idxViewDocPanel, False)
self.splitMain.setStretchFactor(self.idxTree, 0)
self.splitMain.setStretchFactor(self.idxMain, 1)
@@ -277,6 +278,7 @@ class GuiMain(QMainWindow):
self.docEditor.toggleFocusModeRequest.connect(self.toggleFocusMode)
self.docViewer.loadDocumentTagRequest.connect(self._followTag)
self.docViewer.togglePanelVisibility.connect(self._toggleViewerPanelVisibility)
self.outlineView.loadDocumentTagRequest.connect(self._followTag)
self.outlineView.openDocumentRequest.connect(self._openDocument)
@@ -681,7 +683,7 @@ class GuiMain(QMainWindow):
vPos[0] = int(bPos[1]/2)
vPos[1] = bPos[1] - vPos[0]
self.splitDocs.setSizes(vPos)
self.viewMeta.setVisible(CONFIG.showRefPanel)
self.docViewerPanel.setVisible(CONFIG.showViewerPanel)
if sTitle:
self.docViewer.navigateTo(f"#{sTitle}")
@@ -877,6 +879,7 @@ class GuiMain(QMainWindow):
SHARED.theme.loadTheme()
self.docEditor.updateTheme()
self.docViewer.updateTheme()
self.docViewerPanel.updateTheme()
self.sideBar.updateTheme()
self.projView.updateTheme()
self.novelView.updateTheme()
@@ -1076,10 +1079,10 @@ class GuiMain(QMainWindow):
if not self.isFocusMode:
CONFIG.setMainPanePos(self.splitMain.sizes())
CONFIG.setOutlinePanePos(self.outlineView.splitSizes())
if self.viewMeta.isVisible():
if self.docViewerPanel.isVisible():
CONFIG.setViewPanePos(self.splitView.sizes())
CONFIG.showRefPanel = self.viewMeta.isVisible()
CONFIG.showViewerPanel = self.docViewerPanel.isVisible()
if self.windowState() & Qt.WindowFullScreen != Qt.WindowFullScreen:
# Ignore window size if in full screen mode
CONFIG.setMainWinSize(self.width(), self.height())
@@ -1267,6 +1270,13 @@ class GuiMain(QMainWindow):
self.docEditor.insertText(content)
return
@pyqtSlot()
def _toggleViewerPanelVisibility(self):
"""Toggle the visibility of the document viewer panel."""
CONFIG.showViewerPanel = not CONFIG.showViewerPanel
self.docViewerPanel.setVisible(CONFIG.showViewerPanel)
return
@pyqtSlot()
def _timeTick(self) -> None:
"""Process time tick of the main timer."""