diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index f401a9a3..b229827a 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -2837,15 +2837,6 @@ class GuiDocEditHeader(QWidget): self.tbButton.setToolTip(self.tr("Toggle Tool Bar")) self.tbButton.clicked.connect(lambda: self.toggleToolBarRequest.emit()) - self.searchButton = QToolButton(self) - self.searchButton.setContentsMargins(0, 0, 0, 0) - self.searchButton.setIconSize(iconSize) - self.searchButton.setFixedSize(fPx, fPx) - self.searchButton.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly) - self.searchButton.setVisible(False) - self.searchButton.setToolTip(self.tr("Search")) - self.searchButton.clicked.connect(self.docEditor.toggleSearch) - self.outlineButton = QToolButton(self) self.outlineButton.setContentsMargins(0, 0, 0, 0) self.outlineButton.setIconSize(iconSize) @@ -2856,6 +2847,15 @@ class GuiDocEditHeader(QWidget): self.outlineButton.setMenu(self.outlineMenu) self.outlineButton.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup) + self.searchButton = QToolButton(self) + self.searchButton.setContentsMargins(0, 0, 0, 0) + self.searchButton.setIconSize(iconSize) + self.searchButton.setFixedSize(fPx, fPx) + self.searchButton.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly) + self.searchButton.setVisible(False) + self.searchButton.setToolTip(self.tr("Search")) + self.searchButton.clicked.connect(self.docEditor.toggleSearch) + self.minmaxButton = QToolButton(self) self.minmaxButton.setContentsMargins(0, 0, 0, 0) self.minmaxButton.setIconSize(iconSize) @@ -2878,8 +2878,8 @@ class GuiDocEditHeader(QWidget): self.outerBox = QHBoxLayout() self.outerBox.setSpacing(hSp) self.outerBox.addWidget(self.tbButton, 0) - self.outerBox.addWidget(self.searchButton, 0) self.outerBox.addWidget(self.outlineButton, 0) + self.outerBox.addWidget(self.searchButton, 0) self.outerBox.addWidget(self.itemTitle, 1) self.outerBox.addSpacing(fPx + hSp) self.outerBox.addWidget(self.minmaxButton, 0) @@ -2914,8 +2914,8 @@ class GuiDocEditHeader(QWidget): self.itemTitle.setText("") self.outlineMenu.clear() self.tbButton.setVisible(False) - self.searchButton.setVisible(False) self.outlineButton.setVisible(False) + self.searchButton.setVisible(False) self.closeButton.setVisible(False) self.minmaxButton.setVisible(False) return @@ -2937,8 +2937,8 @@ class GuiDocEditHeader(QWidget): def updateTheme(self) -> None: """Update theme elements.""" self.tbButton.setIcon(SHARED.theme.getIcon("menu")) - self.searchButton.setIcon(SHARED.theme.getIcon("search")) self.outlineButton.setIcon(SHARED.theme.getIcon("list")) + self.searchButton.setIcon(SHARED.theme.getIcon("search")) self.minmaxButton.setIcon(SHARED.theme.getIcon("maximise")) self.closeButton.setIcon(SHARED.theme.getIcon("close")) @@ -2950,8 +2950,8 @@ class GuiDocEditHeader(QWidget): buttonStyleMenu = f"{buttonStyle} QToolButton::menu-indicator {{image: none;}}" self.tbButton.setStyleSheet(buttonStyle) - self.searchButton.setStyleSheet(buttonStyle) self.outlineButton.setStyleSheet(buttonStyleMenu) + self.searchButton.setStyleSheet(buttonStyle) self.minmaxButton.setStyleSheet(buttonStyle) self.closeButton.setStyleSheet(buttonStyle) diff --git a/novelwriter/gui/docviewer.py b/novelwriter/gui/docviewer.py index 0dcb2048..eab156ec 100644 --- a/novelwriter/gui/docviewer.py +++ b/novelwriter/gui/docviewer.py @@ -43,7 +43,7 @@ from PyQt5.QtWidgets import ( from novelwriter import CONFIG, SHARED from novelwriter.enum import nwItemType, nwDocAction, nwDocMode from novelwriter.error import logException -from novelwriter.constants import nwUnicode +from novelwriter.constants import nwHeaders, nwUnicode from novelwriter.core.tohtml import ToHtml from novelwriter.extensions.eventfilters import WheelEventFilter @@ -235,7 +235,7 @@ class GuiDocViewer(QTextBrowser): SHARED.project.data.setLastHandle(tHandle, "viewer") self.docHeader.setHandle(tHandle) self.docHeader.setOutline({ - sTitle: hItem.title + sTitle: (hItem.title, nwHeaders.H_LEVEL.get(hItem.level, 0)) for sTitle, hItem in SHARED.project.index.iterItemHeadings(tHandle) }) self.updateDocMargins() @@ -628,7 +628,7 @@ class GuiDocViewHeader(QWidget): # Internal Variables self._docHandle = None - self._docOutline: dict[int, str] = {} + self._docOutline: dict[int, tuple[str, int]] = {} fPx = int(0.9*SHARED.theme.fontPixelSize) hSp = CONFIG.pxInt(6) @@ -656,6 +656,16 @@ class GuiDocViewHeader(QWidget): self.outlineMenu = QMenu(self) # Buttons + self.outlineButton = QToolButton(self) + self.outlineButton.setContentsMargins(0, 0, 0, 0) + self.outlineButton.setIconSize(iconSize) + self.outlineButton.setFixedSize(fPx, fPx) + self.outlineButton.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly) + self.outlineButton.setVisible(False) + self.outlineButton.setToolTip(self.tr("Outline")) + self.outlineButton.setMenu(self.outlineMenu) + self.outlineButton.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup) + self.backButton = QToolButton(self) self.backButton.setContentsMargins(0, 0, 0, 0) self.backButton.setIconSize(iconSize) @@ -674,16 +684,6 @@ class GuiDocViewHeader(QWidget): self.forwardButton.setToolTip(self.tr("Go Forward")) self.forwardButton.clicked.connect(self.docViewer.navForward) - self.outlineButton = QToolButton(self) - self.outlineButton.setContentsMargins(0, 0, 0, 0) - self.outlineButton.setIconSize(iconSize) - self.outlineButton.setFixedSize(fPx, fPx) - self.outlineButton.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly) - self.outlineButton.setVisible(False) - self.outlineButton.setToolTip(self.tr("Outline")) - self.outlineButton.setMenu(self.outlineMenu) - self.outlineButton.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup) - self.refreshButton = QToolButton(self) self.refreshButton.setContentsMargins(0, 0, 0, 0) self.refreshButton.setIconSize(iconSize) @@ -705,9 +705,9 @@ class GuiDocViewHeader(QWidget): # Assemble Layout self.outerBox = QHBoxLayout() self.outerBox.setSpacing(hSp) + self.outerBox.addWidget(self.outlineButton, 0) self.outerBox.addWidget(self.backButton, 0) self.outerBox.addWidget(self.forwardButton, 0) - self.outerBox.addWidget(self.outlineButton, 0) self.outerBox.addWidget(self.itemTitle, 1) self.outerBox.addSpacing(fPx + hSp) self.outerBox.addWidget(self.refreshButton, 0) @@ -739,19 +739,26 @@ class GuiDocViewHeader(QWidget): self.itemTitle.setText("") self.outlineMenu.clear() + self.outlineButton.setVisible(False) self.backButton.setVisible(False) self.forwardButton.setVisible(False) - self.outlineButton.setVisible(False) self.closeButton.setVisible(False) self.refreshButton.setVisible(False) return - def setOutline(self, data: dict[int, str]) -> None: + def setOutline(self, data: dict[int, tuple[str, int]]) -> None: """Set the document outline dataset.""" if data != self._docOutline: self.outlineMenu.clear() - for title, text in data.items(): - action = self.outlineMenu.addAction(text) + entries = [] + minLevel = 5 + for title, (text, level) in data.items(): + if title != "T0000": + entries.append((title, text, level)) + minLevel = min(minLevel, level) + for title, text, level in entries: + indent = " "*(level - minLevel) + action = self.outlineMenu.addAction(f"{indent}{text}") action.triggered.connect( lambda _, title=title: self.docViewer.navigateTo(f"#{title}") ) @@ -760,9 +767,9 @@ class GuiDocViewHeader(QWidget): def updateTheme(self) -> None: """Update theme elements.""" + self.outlineButton.setIcon(SHARED.theme.getIcon("list")) self.backButton.setIcon(SHARED.theme.getIcon("backward")) self.forwardButton.setIcon(SHARED.theme.getIcon("forward")) - self.outlineButton.setIcon(SHARED.theme.getIcon("list")) self.refreshButton.setIcon(SHARED.theme.getIcon("refresh")) self.closeButton.setIcon(SHARED.theme.getIcon("close")) @@ -773,9 +780,9 @@ class GuiDocViewHeader(QWidget): ).format(colText.red(), colText.green(), colText.blue()) buttonStyleMenu = f"{buttonStyle} QToolButton::menu-indicator {{image: none;}}" + self.outlineButton.setStyleSheet(buttonStyleMenu) self.backButton.setStyleSheet(buttonStyle) self.forwardButton.setStyleSheet(buttonStyle) - self.outlineButton.setStyleSheet(buttonStyleMenu) self.refreshButton.setStyleSheet(buttonStyle) self.closeButton.setStyleSheet(buttonStyle) diff --git a/tests/test_core/test_core_index.py b/tests/test_core/test_core_index.py index 3ae976d4..13ba42dd 100644 --- a/tests/test_core/test_core_index.py +++ b/tests/test_core/test_core_index.py @@ -705,6 +705,16 @@ def testCoreIndex_ExtractData(mockGUI, fncPath, mockRnd): index.getItemHeading(dHandle, "T0001") )] + # getItemHeading + # ============== + assert list(index.iterItemHeadings(cHandle)) == [ + ("T0001", index.getItemHeading(cHandle, "T0001")) + ] + assert list(index.iterItemHeadings(dHandle)) == [ + ("T0001", index.getItemHeading(dHandle, "T0001")) + ] + assert list(index.iterItemHeadings(C.hInvalid)) == [] + # getSingleTag # ============ assert index.getSingleTag("jane") == (