diff --git a/novelwriter/assets/icons/typicons_dark/icons.conf b/novelwriter/assets/icons/typicons_dark/icons.conf index c51b2457..999ce000 100644 --- a/novelwriter/assets/icons/typicons_dark/icons.conf +++ b/novelwriter/assets/icons/typicons_dark/icons.conf @@ -91,14 +91,21 @@ sticky-off = typ_pin-outline.svg sticky-on = typ_pin.svg unchecked = mixed_input-unchecked.svg up = typ_chevron-up.svg +view = typ_eye.svg view_build = typ_export-grey.svg view_editor = mixed_edit.svg view_novel = typ_book-grey.svg view_outline = typ_puzzle-outline.svg deco_doc_h0 = nw_deco-h0.svg +deco_doc_h0_n = nw_deco-h0.svg deco_doc_h1 = nw_deco-h1.svg +deco_doc_h1_n = nw_deco-h1.svg deco_doc_h2 = nw_deco-h2.svg +deco_doc_h2_n = nw_deco-h2-narrow.svg deco_doc_h3 = nw_deco-h3.svg +deco_doc_h3_n = nw_deco-h3-narrow.svg deco_doc_h4 = nw_deco-h4.svg +deco_doc_h4_n = nw_deco-h4-narrow.svg deco_doc_more = nw_deco-noveltree-more.svg +deco_doc_nt_n = nw_deco-note.svg diff --git a/novelwriter/assets/icons/typicons_dark/nw_deco-h2-narrow.svg b/novelwriter/assets/icons/typicons_dark/nw_deco-h2-narrow.svg new file mode 100644 index 00000000..ced9f866 --- /dev/null +++ b/novelwriter/assets/icons/typicons_dark/nw_deco-h2-narrow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/novelwriter/assets/icons/typicons_dark/nw_deco-h3-narrow.svg b/novelwriter/assets/icons/typicons_dark/nw_deco-h3-narrow.svg new file mode 100644 index 00000000..e5a9fad9 --- /dev/null +++ b/novelwriter/assets/icons/typicons_dark/nw_deco-h3-narrow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/novelwriter/assets/icons/typicons_dark/nw_deco-h4-narrow.svg b/novelwriter/assets/icons/typicons_dark/nw_deco-h4-narrow.svg new file mode 100644 index 00000000..3394646e --- /dev/null +++ b/novelwriter/assets/icons/typicons_dark/nw_deco-h4-narrow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/novelwriter/assets/icons/typicons_dark/nw_deco-note.svg b/novelwriter/assets/icons/typicons_dark/nw_deco-note.svg new file mode 100644 index 00000000..85944eb6 --- /dev/null +++ b/novelwriter/assets/icons/typicons_dark/nw_deco-note.svg @@ -0,0 +1,4 @@ + + + + diff --git a/novelwriter/assets/icons/typicons_dark/typ_eye.svg b/novelwriter/assets/icons/typicons_dark/typ_eye.svg new file mode 100644 index 00000000..34d22862 --- /dev/null +++ b/novelwriter/assets/icons/typicons_dark/typ_eye.svg @@ -0,0 +1,4 @@ + + + + diff --git a/novelwriter/assets/icons/typicons_light/icons.conf b/novelwriter/assets/icons/typicons_light/icons.conf index 5f300ad2..3c6f545c 100644 --- a/novelwriter/assets/icons/typicons_light/icons.conf +++ b/novelwriter/assets/icons/typicons_light/icons.conf @@ -91,14 +91,21 @@ sticky-off = typ_pin-outline.svg sticky-on = typ_pin.svg unchecked = mixed_input-unchecked.svg up = typ_chevron-up.svg +view = typ_eye.svg view_build = typ_export-grey.svg view_editor = mixed_edit.svg view_novel = typ_book-grey.svg view_outline = typ_puzzle-outline.svg deco_doc_h0 = nw_deco-h0.svg +deco_doc_h0_n = nw_deco-h0.svg deco_doc_h1 = nw_deco-h1.svg +deco_doc_h1_n = nw_deco-h1.svg deco_doc_h2 = nw_deco-h2.svg +deco_doc_h2_n = nw_deco-h2-narrow.svg deco_doc_h3 = nw_deco-h3.svg +deco_doc_h3_n = nw_deco-h3-narrow.svg deco_doc_h4 = nw_deco-h4.svg +deco_doc_h4_n = nw_deco-h4-narrow.svg deco_doc_more = nw_deco-noveltree-more.svg +deco_doc_nt_n = nw_deco-note.svg diff --git a/novelwriter/assets/icons/typicons_light/nw_deco-h2-narrow.svg b/novelwriter/assets/icons/typicons_light/nw_deco-h2-narrow.svg new file mode 100644 index 00000000..fe43924d --- /dev/null +++ b/novelwriter/assets/icons/typicons_light/nw_deco-h2-narrow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/novelwriter/assets/icons/typicons_light/nw_deco-h3-narrow.svg b/novelwriter/assets/icons/typicons_light/nw_deco-h3-narrow.svg new file mode 100644 index 00000000..79a75ac4 --- /dev/null +++ b/novelwriter/assets/icons/typicons_light/nw_deco-h3-narrow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/novelwriter/assets/icons/typicons_light/nw_deco-h4-narrow.svg b/novelwriter/assets/icons/typicons_light/nw_deco-h4-narrow.svg new file mode 100644 index 00000000..7a7279bc --- /dev/null +++ b/novelwriter/assets/icons/typicons_light/nw_deco-h4-narrow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/novelwriter/assets/icons/typicons_light/nw_deco-note.svg b/novelwriter/assets/icons/typicons_light/nw_deco-note.svg new file mode 100644 index 00000000..972d71c7 --- /dev/null +++ b/novelwriter/assets/icons/typicons_light/nw_deco-note.svg @@ -0,0 +1,4 @@ + + + + diff --git a/novelwriter/assets/icons/typicons_light/typ_eye.svg b/novelwriter/assets/icons/typicons_light/typ_eye.svg new file mode 100644 index 00000000..9cae4229 --- /dev/null +++ b/novelwriter/assets/icons/typicons_light/typ_eye.svg @@ -0,0 +1,4 @@ + + + + diff --git a/novelwriter/gui/docviewerpanel.py b/novelwriter/gui/docviewerpanel.py index 2b780060..a85c8446 100644 --- a/novelwriter/gui/docviewerpanel.py +++ b/novelwriter/gui/docviewerpanel.py @@ -27,7 +27,7 @@ import logging from PyQt5.QtCore import QSize, Qt, pyqtSlot from PyQt5.QtWidgets import ( - QFrame, QHBoxLayout, QHeaderView, QTabWidget, QTreeWidget, QTreeWidgetItem, + QAbstractItemView, QFrame, QHBoxLayout, QHeaderView, QTabWidget, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget ) @@ -44,10 +44,12 @@ class GuiDocViewerPanel(QWidget): logger.debug("Create: GuiDocViewerPanel") + self._lastHandle = None + self.tabBackRefs = _ViewPanelBackRefs(self) self.mainTabs = QTabWidget(self) - self.mainTabs.addTab(self.tabBackRefs, self.tr("Back References")) + self.mainTabs.addTab(self.tabBackRefs, self.tr("Backreferences")) self.kwTabs = {} for itemClass in nwLists.USER_CLASSES: @@ -83,6 +85,7 @@ class GuiDocViewerPanel(QWidget): "} " ) self.mainTabs.setStyleSheet(styleSheet) + self.updateHandle(self._lastHandle) return @@ -93,6 +96,7 @@ class GuiDocViewerPanel(QWidget): @pyqtSlot(str) def updateHandle(self, tHandle: str | None) -> None: """Update the document handle.""" + self._lastHandle = tHandle self.tabBackRefs.refreshContent(tHandle or None) return @@ -101,10 +105,11 @@ class GuiDocViewerPanel(QWidget): class _ViewPanelBackRefs(QWidget): - C_DATA = 0 - C_TITLE = 0 - C_NAME = 1 - C_SYNOPSIS = 2 + C_DATA = 0 + C_TITLE = 0 + C_EDIT = 1 + C_VIEW = 2 + C_NAME = 3 D_HANDLE = Qt.ItemDataRole.UserRole D_TITLE = Qt.ItemDataRole.UserRole + 1 @@ -113,22 +118,28 @@ class _ViewPanelBackRefs(QWidget): super().__init__(parent=parent) iPx = SHARED.theme.baseIconSize + cMg = CONFIG.pxInt(6) # Content self.listBox = QTreeWidget(self) # self.listBox.setHeaderHidden(True) - # self.listBox.setColumnCount(3) + # self.listBox.setColumnCount(4) self.listBox.setHeaderLabels([ - self.tr("Title"), self.tr("Document"), self.tr("Synopsis") + self.tr("Title"), "", "", self.tr("Document") ]) self.listBox.setIndentation(0) + self.listBox.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection) self.listBox.setIconSize(QSize(iPx, iPx)) self.listBox.setFrameStyle(QFrame.Shape.NoFrame) treeHeader = self.listBox.header() treeHeader.setStretchLastSection(True) + treeHeader.setSectionResizeMode(self.C_EDIT, QHeaderView.ResizeMode.Fixed) + treeHeader.setSectionResizeMode(self.C_VIEW, QHeaderView.ResizeMode.Fixed) treeHeader.setSectionResizeMode(self.C_NAME, QHeaderView.ResizeMode.ResizeToContents) treeHeader.setSectionResizeMode(self.C_TITLE, QHeaderView.ResizeMode.ResizeToContents) + treeHeader.resizeSection(self.C_EDIT, iPx + cMg) + treeHeader.resizeSection(self.C_VIEW, iPx + cMg) fH1 = self.font() fH1.setBold(True) @@ -137,7 +148,9 @@ class _ViewPanelBackRefs(QWidget): fH2 = self.font() fH2.setBold(True) - self._hFonts = [self.font(), fH1, fH2, self.font(), self.font()] + self._hFonts = [self.font(), fH1, fH2, self.font(), self.font(), self.font()] + self._editIcon = SHARED.theme.getIcon("edit") + self._viewIcon = SHARED.theme.getIcon("view") # Assemble self.outerBox = QHBoxLayout() @@ -159,20 +172,21 @@ class _ViewPanelBackRefs(QWidget): if nwItem is None: continue - icon = SHARED.theme.getItemIcon( + docIcon = SHARED.theme.getItemIcon( nwItem.itemType, nwItem.itemClass, nwItem.itemLayout, nwItem.mainHeading ) - iLevel = nwHeaders.H_LEVEL.get(hItem.level, 0) - hDec = SHARED.theme.getHeaderDecoration(iLevel) + iLevel = nwHeaders.H_LEVEL.get(hItem.level, 0) if nwItem.isDocumentLayout() else 5 + hDec = SHARED.theme.getHeaderDecorationNarrow(iLevel) trItem = QTreeWidgetItem() trItem.setText(self.C_TITLE, hItem.title) trItem.setData(self.C_TITLE, Qt.ItemDataRole.DecorationRole, hDec) trItem.setFont(self.C_TITLE, self._hFonts[iLevel]) - trItem.setIcon(self.C_NAME, icon) + trItem.setIcon(self.C_EDIT, self._editIcon) + trItem.setIcon(self.C_VIEW, self._viewIcon) + trItem.setIcon(self.C_NAME, docIcon) trItem.setText(self.C_NAME, nwItem.itemName) - trItem.setText(self.C_SYNOPSIS, hItem.synopsis) trItem.setData(self.C_DATA, self.D_HANDLE, tHandle) trItem.setData(self.C_DATA, self.D_TITLE, sTitle) diff --git a/novelwriter/gui/theme.py b/novelwriter/gui/theme.py index a169e6f8..4ac8b714 100644 --- a/novelwriter/gui/theme.py +++ b/novelwriter/gui/theme.py @@ -133,6 +133,7 @@ class GuiTheme: self.getToggleIcon = self.iconCache.getToggleIcon self.loadDecoration = self.iconCache.loadDecoration self.getHeaderDecoration = self.iconCache.getHeaderDecoration + self.getHeaderDecorationNarrow = self.iconCache.getHeaderDecorationNarrow # Extract Other Info self.guiDPI = qApp.primaryScreen().logicalDotsPerInchX() @@ -465,7 +466,7 @@ class GuiIcons: # General Button Icons "add", "backward", "bookmark", "browse", "checked", "close", "cross", "down", "edit", "export", "forward", "maximise", "menu", "minimise", "noncheckable", "panel", "refresh", - "remove", "revert", "search_replace", "search", "settings", "unchecked", "up", + "remove", "revert", "search_replace", "search", "settings", "unchecked", "up", "view", # Switches "sticky-on", "sticky-off", @@ -473,6 +474,8 @@ class GuiIcons: # Decorations "deco_doc_h0", "deco_doc_h1", "deco_doc_h2", "deco_doc_h3", "deco_doc_h4", "deco_doc_more", + "deco_doc_h0_n", "deco_doc_h1_n", "deco_doc_h2_n", "deco_doc_h3_n", "deco_doc_h4_n", + "deco_doc_nt_n", } TOGGLE_ICON_KEYS = { @@ -493,6 +496,7 @@ class GuiIcons: self._qIcons: dict[str, QIcon] = {} self._themeMap: dict[str, Path] = {} self._headerDec: list[QPixmap] = [] + self._headerDecNarrow: list[QPixmap] = [] # Icon Theme Path self._confName = "icons.conf" @@ -580,6 +584,7 @@ class GuiIcons: self._qIcons[iconKey] = qIcon self._headerDec = [] + self._headerDecNarrow = [] return True @@ -680,6 +685,20 @@ class GuiIcons: ] return self._headerDec[minmax(hLevel, 0, 4)] + def getHeaderDecorationNarrow(self, hLevel: int) -> QPixmap: + """Get the narrow decoration for a specific header level.""" + if not self._headerDecNarrow: + iPx = self.mainTheme.baseIconSize + self._headerDecNarrow = [ + self.loadDecoration("deco_doc_h0_n", h=iPx), + self.loadDecoration("deco_doc_h1_n", h=iPx), + self.loadDecoration("deco_doc_h2_n", h=iPx), + self.loadDecoration("deco_doc_h3_n", h=iPx), + self.loadDecoration("deco_doc_h4_n", h=iPx), + self.loadDecoration("deco_doc_nt_n", h=iPx), + ] + return self._headerDecNarrow[minmax(hLevel, 0, 5)] + ## # Internal Functions ##