Clean up warnings and deprecations in gui components

This commit is contained in:
Veronica Berglyd Olsen
2025-01-13 02:21:56 +01:00
parent a60e0b3c87
commit 5027b8df19
14 changed files with 458 additions and 474 deletions
+16 -1
View File
@@ -38,7 +38,8 @@ from urllib.parse import urljoin
from urllib.request import pathname2url
from PyQt6.QtCore import QCoreApplication, QMimeData, QUrl
from PyQt6.QtGui import QColor, QDesktopServices, QFont, QFontDatabase, QFontInfo
from PyQt6.QtGui import QAction, QColor, QDesktopServices, QFont, QFontDatabase, QFontInfo
from PyQt6.QtWidgets import QMenu, QMenuBar, QWidget
from novelwriter.constants import nwConst, nwLabels, nwUnicode, trConst
from novelwriter.enum import nwItemClass, nwItemLayout, nwItemType
@@ -461,6 +462,20 @@ def qtLambda(func: Callable, *args: Any, **kwargs: Any) -> Callable:
return wrapper
def qtAddAction(parent: QWidget, label: str) -> QAction:
"""Helper to add action to widget and always return the action."""
action = QAction(label, parent)
parent.addAction(action)
return action
def qtAddMenu(parent: QMenuBar | QMenu, label: str) -> QMenu:
"""Helper to add menu to menu and always return the menu."""
menu = QMenu(label, parent)
parent.addMenu(menu)
return menu
def encodeMimeHandles(mimeData: QMimeData, handles: list[str]) -> None:
"""Encode handles into a mime data object."""
mimeData.setData(nwConst.MIME_HANDLE, b"|".join(h.encode() for h in handles))
+85 -90
View File
@@ -52,7 +52,9 @@ from PyQt6.QtWidgets import (
)
from novelwriter import CONFIG, SHARED
from novelwriter.common import decodeMimeHandles, fontMatcher, minmax, qtLambda, transferCase
from novelwriter.common import (
decodeMimeHandles, fontMatcher, minmax, qtAddAction, qtLambda, transferCase
)
from novelwriter.constants import nwConst, nwKeyWords, nwShortcode, nwUnicode
from novelwriter.core.document import NWDocument
from novelwriter.enum import (
@@ -168,7 +170,7 @@ class GuiDocEditor(QPlainTextEdit):
self.customContextMenuRequested.connect(self._openContextMenu)
# Editor Settings
self.setMinimumWidth(CONFIG.pxInt(300))
self.setMinimumWidth(300)
self.setAutoFillBackground(True)
self.setFrameStyle(QFrame.Shape.NoFrame)
self.setAcceptDrops(True)
@@ -295,10 +297,11 @@ class GuiDocEditor(QPlainTextEdit):
palette.setColor(QPalette.ColorRole.Text, syntax.text)
self.setPalette(palette)
palette = self.viewport().palette()
palette.setColor(QPalette.ColorRole.Base, syntax.back)
palette.setColor(QPalette.ColorRole.Text, syntax.text)
self.viewport().setPalette(palette)
if viewport := self.viewport():
palette = viewport.palette()
palette.setColor(QPalette.ColorRole.Base, syntax.back)
palette.setColor(QPalette.ColorRole.Text, syntax.text)
viewport.setPalette(palette)
self.docHeader.matchColours()
self.docFooter.matchColours()
@@ -513,29 +516,27 @@ class GuiDocEditor(QPlainTextEdit):
def cursorIsVisible(self) -> bool:
"""Check if the cursor is visible in the editor."""
return (
0 < self.cursorRect().top()
and self.cursorRect().bottom() < self.viewport().height()
)
viewport = self.viewport()
height = viewport.height() if viewport else 0
return 0 < self.cursorRect().top() and self.cursorRect().bottom() < height
def ensureCursorVisibleNoCentre(self) -> None:
"""Ensure cursor is visible, but don't force it to centre."""
cT = self.cursorRect().top()
cB = self.cursorRect().bottom()
vH = self.viewport().height()
if cT < 0:
count = 0
vBar = self.verticalScrollBar()
while self.cursorRect().top() < 0 and count < 100000:
vBar.setValue(vBar.value() - 1)
count += 1
elif cB > vH:
count = 0
vBar = self.verticalScrollBar()
while self.cursorRect().bottom() > vH and count < 100000:
vBar.setValue(vBar.value() + 1)
count += 1
QApplication.processEvents()
if (viewport := self.viewport()) and (vBar := self.verticalScrollBar()):
cT = self.cursorRect().top()
cB = self.cursorRect().bottom()
vH = viewport.height()
if cT < 0:
count = 0
while self.cursorRect().top() < 0 and count < 100000:
vBar.setValue(vBar.value() - 1)
count += 1
elif cB > vH:
count = 0
while self.cursorRect().bottom() > vH and count < 100000:
vBar.setValue(vBar.value() + 1)
count += 1
QApplication.processEvents()
return
def updateDocMargins(self) -> None:
@@ -547,10 +548,10 @@ class GuiDocEditor(QPlainTextEdit):
wH = self.height()
vBar = self.verticalScrollBar()
sW = vBar.width() if vBar.isVisible() else 0
sW = vBar.width() if vBar and vBar.isVisible() else 0
hBar = self.horizontalScrollBar()
sH = hBar.height() if hBar.isVisible() else 0
sH = hBar.height() if hBar and hBar.isVisible() else 0
tM = self._vpMargin
if CONFIG.textWidth > 0 or SHARED.focusMode:
@@ -959,10 +960,9 @@ class GuiDocEditor(QPlainTextEdit):
kMod = event.modifiers()
okMod = kMod in (QtModNone, QtModShift)
okKey = event.key() not in self.MOVE_KEYS
if nPos != cPos and okMod and okKey:
mPos = CONFIG.autoScrollPos*0.01 * self.viewport().height()
if cPos > mPos:
vBar = self.verticalScrollBar()
if nPos != cPos and okMod and okKey and (viewport := self.viewport()):
mPos = CONFIG.autoScrollPos*0.01 * viewport.height()
if cPos > mPos and (vBar := self.verticalScrollBar()):
vBar.setValue(vBar.value() + (1 if nPos > cPos else -1))
else:
super().keyPressEvent(event)
@@ -971,7 +971,7 @@ class GuiDocEditor(QPlainTextEdit):
def dragEnterEvent(self, event: QDragEnterEvent) -> None:
"""Overload drag enter event to handle dragged items."""
if event.mimeData().hasFormat(nwConst.MIME_HANDLE):
if (data := event.mimeData()) and data.hasFormat(nwConst.MIME_HANDLE):
event.acceptProposedAction()
else:
super().dragEnterEvent(event)
@@ -979,7 +979,7 @@ class GuiDocEditor(QPlainTextEdit):
def dragMoveEvent(self, event: QDragMoveEvent) -> None:
"""Overload drag move event to handle dragged items."""
if event.mimeData().hasFormat(nwConst.MIME_HANDLE):
if (data := event.mimeData()) and data.hasFormat(nwConst.MIME_HANDLE):
event.acceptProposedAction()
else:
super().dragMoveEvent(event)
@@ -987,8 +987,8 @@ class GuiDocEditor(QPlainTextEdit):
def dropEvent(self, event: QDropEvent) -> None:
"""Overload drop event to handle dragged items."""
if event.mimeData().hasFormat(nwConst.MIME_HANDLE):
if handles := decodeMimeHandles(event.mimeData()):
if (data := event.mimeData()) and data.hasFormat(nwConst.MIME_HANDLE):
if handles := decodeMimeHandles(data):
if SHARED.project.tree.checkType(handles[0], nwItemType.FILE):
self.openDocumentRequest.emit(handles[0], nwDocMode.EDIT, "", True)
else:
@@ -1098,10 +1098,10 @@ class GuiDocEditor(QPlainTextEdit):
# at unwanted times when other changes are made to the document
cursor = self.textCursor()
bPos = cursor.positionInBlock()
if bPos > 0:
if bPos > 0 and (viewport := self.viewport()):
show = self._completer.updateText(text, bPos)
point = self.cursorRect().bottomRight()
self._completer.move(self.viewport().mapToGlobal(point))
self._completer.move(viewport.mapToGlobal(point))
self._completer.setVisible(show)
else:
self._completer.setVisible(False)
@@ -1148,46 +1148,46 @@ class GuiDocEditor(QPlainTextEdit):
ctxMenu = QMenu(self)
ctxMenu.setObjectName("ContextMenu")
if pBlock.userState() == BLOCK_TITLE:
action = ctxMenu.addAction(self.tr("Set as Document Name"))
action = qtAddAction(ctxMenu, self.tr("Set as Document Name"))
action.triggered.connect(qtLambda(self._emitRenameItem, pBlock))
# URL
(mData, mType) = self._qDocument.metaDataAtPos(pCursor.position())
if mData and mType == "url":
action = ctxMenu.addAction(self.tr("Open URL"))
action = qtAddAction(ctxMenu, self.tr("Open URL"))
action.triggered.connect(qtLambda(SHARED.openWebsite, mData))
ctxMenu.addSeparator()
# Follow
status = self._processTag(cursor=pCursor, follow=False)
if status == nwTrinary.POSITIVE:
action = ctxMenu.addAction(self.tr("Follow Tag"))
action = qtAddAction(ctxMenu, self.tr("Follow Tag"))
action.triggered.connect(qtLambda(self._processTag, cursor=pCursor, follow=True))
ctxMenu.addSeparator()
elif status == nwTrinary.NEGATIVE:
action = ctxMenu.addAction(self.tr("Create Note for Tag"))
action = qtAddAction(ctxMenu, self.tr("Create Note for Tag"))
action.triggered.connect(qtLambda(self._processTag, cursor=pCursor, create=True))
ctxMenu.addSeparator()
# Cut, Copy and Paste
if uCursor.hasSelection():
action = ctxMenu.addAction(self.tr("Cut"))
action = qtAddAction(ctxMenu, self.tr("Cut"))
action.triggered.connect(qtLambda(self.docAction, nwDocAction.CUT))
action = ctxMenu.addAction(self.tr("Copy"))
action = qtAddAction(ctxMenu, self.tr("Copy"))
action.triggered.connect(qtLambda(self.docAction, nwDocAction.COPY))
action = ctxMenu.addAction(self.tr("Paste"))
action = qtAddAction(ctxMenu, self.tr("Paste"))
action.triggered.connect(qtLambda(self.docAction, nwDocAction.PASTE))
ctxMenu.addSeparator()
# Selections
action = ctxMenu.addAction(self.tr("Select All"))
action = qtAddAction(ctxMenu, self.tr("Select All"))
action.triggered.connect(qtLambda(self.docAction, nwDocAction.SEL_ALL))
action = ctxMenu.addAction(self.tr("Select Word"))
action = qtAddAction(ctxMenu, self.tr("Select Word"))
action.triggered.connect(qtLambda(
self._makePosSelection, QTextCursor.SelectionType.WordUnderCursor, pos,
))
action = ctxMenu.addAction(self.tr("Select Paragraph"))
action = qtAddAction(ctxMenu, self.tr("Select Paragraph"))
action.triggered.connect(qtLambda(
self._makePosSelection, QTextCursor.SelectionType.BlockUnderCursor, pos
))
@@ -1203,23 +1203,24 @@ class GuiDocEditor(QPlainTextEdit):
sCursor.movePosition(QtMoveRight, QtKeepAnchor, cLen)
if suggest:
ctxMenu.addSeparator()
ctxMenu.addAction(self.tr("Spelling Suggestion(s)"))
qtAddAction(ctxMenu, self.tr("Spelling Suggestion(s)"))
for option in suggest[:15]:
action = ctxMenu.addAction(f"{nwUnicode.U_ENDASH} {option}")
action = qtAddAction(ctxMenu, f"{nwUnicode.U_ENDASH} {option}")
action.triggered.connect(qtLambda(self._correctWord, sCursor, option))
else:
trNone = self.tr("No Suggestions")
ctxMenu.addAction(f"{nwUnicode.U_ENDASH} {trNone}")
qtAddAction(ctxMenu, f"{nwUnicode.U_ENDASH} {trNone}")
ctxMenu.addSeparator()
action = ctxMenu.addAction(self.tr("Ignore Word"))
action = qtAddAction(ctxMenu, self.tr("Ignore Word"))
action.triggered.connect(qtLambda(self._addWord, word, block, False))
action = ctxMenu.addAction(self.tr("Add Word to Dictionary"))
action = qtAddAction(ctxMenu, self.tr("Add Word to Dictionary"))
action.triggered.connect(qtLambda(self._addWord, word, block, True))
# Execute the context menu
ctxMenu.exec(self.viewport().mapToGlobal(pos))
ctxMenu.deleteLater()
if viewport := self.viewport():
ctxMenu.exec(viewport.mapToGlobal(pos))
ctxMenu.deleteLater()
return
@@ -2007,8 +2008,8 @@ class GuiDocEditor(QPlainTextEdit):
sPos = cPos
for i in range(cPos - bPos):
sPos = cPos - i - 1
cOne = self._qDocument.characterAt(sPos)
cTwo = self._qDocument.characterAt(sPos - 1)
cOne = str(self._qDocument.characterAt(sPos))
cTwo = str(self._qDocument.characterAt(sPos - 1))
if not (cOne.isalnum() or cOne in apos and cTwo.isalnum()):
sPos += 1
break
@@ -2017,8 +2018,8 @@ class GuiDocEditor(QPlainTextEdit):
ePos = cPos
for i in range(bPos + bLen - cPos):
ePos = cPos + i
cOne = self._qDocument.characterAt(ePos)
cTwo = self._qDocument.characterAt(ePos + 1)
cOne = str(self._qDocument.characterAt(ePos))
cTwo = str(self._qDocument.characterAt(ePos + 1))
if not (cOne.isalnum() or cOne in apos and cTwo.isalnum()):
break
@@ -2122,7 +2123,7 @@ class MetaCompleter(QMenu):
for value in sorted(options):
rep = value + suffix
action = self.addAction(value)
action = qtAddAction(self, value)
action.triggered.connect(qtLambda(self._emitComplete, offset, length, rep))
return True
@@ -2339,7 +2340,6 @@ class GuiDocToolBar(QWidget):
logger.debug("Create: GuiDocToolBar")
iSz = SHARED.theme.baseIconSize
cM = CONFIG.pxInt(4)
self.setContentsMargins(0, 0, 0, 0)
# General Buttons
@@ -2412,7 +2412,7 @@ class GuiDocToolBar(QWidget):
self.outerBox.addWidget(self.tbBoldMD)
self.outerBox.addWidget(self.tbItalicMD)
self.outerBox.addWidget(self.tbStrikeMD)
self.outerBox.addSpacing(cM)
self.outerBox.addSpacing(4)
self.outerBox.addWidget(self.tbBold)
self.outerBox.addWidget(self.tbItalic)
self.outerBox.addWidget(self.tbStrike)
@@ -2420,8 +2420,8 @@ class GuiDocToolBar(QWidget):
self.outerBox.addWidget(self.tbMark)
self.outerBox.addWidget(self.tbSuperscript)
self.outerBox.addWidget(self.tbSubscript)
self.outerBox.setContentsMargins(cM, cM, cM, cM)
self.outerBox.setSpacing(cM)
self.outerBox.setContentsMargins(4, 4, 4, 4)
self.outerBox.setSpacing(4)
self.setLayout(self.outerBox)
self.updateTheme()
@@ -2472,7 +2472,6 @@ class GuiDocEditSearch(QFrame):
self.docEditor = docEditor
iSz = SHARED.theme.baseIconSize
mPx = CONFIG.pxInt(6)
self.setContentsMargins(0, 0, 0, 0)
self.setAutoFillBackground(True)
@@ -2498,7 +2497,7 @@ class GuiDocEditSearch(QFrame):
self.searchOpt.setContentsMargins(0, 0, 0, 0)
self.searchLabel = QLabel(self.tr("Search"), self)
self.searchLabel.setIndent(CONFIG.pxInt(6))
self.searchLabel.setIndent(6)
self.resultLabel = QLabel("?/?", self)
@@ -2575,12 +2574,11 @@ class GuiDocEditSearch(QFrame):
self.mainBox.setColumnStretch(3, 0)
self.mainBox.setColumnStretch(4, 0)
self.mainBox.setColumnStretch(5, 0)
self.mainBox.setSpacing(CONFIG.pxInt(2))
self.mainBox.setContentsMargins(mPx, mPx, mPx, mPx)
self.mainBox.setSpacing(2)
self.mainBox.setContentsMargins(6, 6, 6, 6)
boxWidth = CONFIG.pxInt(200)
self.searchBox.setFixedWidth(boxWidth)
self.replaceBox.setFixedWidth(boxWidth)
self.searchBox.setFixedWidth(200)
self.replaceBox.setFixedWidth(200)
self.replaceBox.setVisible(False)
self.replaceButton.setVisible(False)
self.adjustSize()
@@ -2848,7 +2846,6 @@ class GuiDocEditHeader(QWidget):
iPx = SHARED.theme.baseIconHeight
iSz = SHARED.theme.baseIconSize
mPx = CONFIG.pxInt(4)
# Main Widget Settings
self.setAutoFillBackground(True)
@@ -2895,13 +2892,13 @@ class GuiDocEditHeader(QWidget):
self.outerBox.addWidget(self.tbButton, 0)
self.outerBox.addWidget(self.outlineButton, 0)
self.outerBox.addWidget(self.searchButton, 0)
self.outerBox.addSpacing(mPx)
self.outerBox.addSpacing(4)
self.outerBox.addWidget(self.itemTitle, 1)
self.outerBox.addSpacing(mPx)
self.outerBox.addSpacing(4)
self.outerBox.addSpacing(iPx)
self.outerBox.addWidget(self.minmaxButton, 0)
self.outerBox.addWidget(self.closeButton, 0)
self.outerBox.setContentsMargins(mPx, mPx, mPx, mPx)
self.outerBox.setContentsMargins(4, 4, 4, 4)
self.outerBox.setSpacing(0)
self.setLayout(self.outerBox)
@@ -2912,7 +2909,7 @@ class GuiDocEditHeader(QWidget):
# Fix Margins and Size
# This is needed for high DPI systems. See issue #499.
self.setContentsMargins(0, 0, 0, 0)
self.setMinimumHeight(iPx + 2*mPx)
self.setMinimumHeight(iPx + 8)
self.updateFont()
self.updateTheme()
@@ -2945,7 +2942,7 @@ class GuiDocEditHeader(QWidget):
tStart = time()
self.outlineMenu.clear()
for number, text in data.items():
action = self.outlineMenu.addAction(text)
action = qtAddAction(self.outlineMenu, text)
action.triggered.connect(qtLambda(self._gotoBlock, number))
self._docOutline = data
logger.debug("Document outline updated in %.3f ms", 1000*(time() - tStart))
@@ -3070,9 +3067,6 @@ class GuiDocEditFooter(QWidget):
iPx = round(0.9*SHARED.theme.baseIconHeight)
fPx = int(0.9*SHARED.theme.fontPixelSize)
mPx = CONFIG.pxInt(8)
bSp = CONFIG.pxInt(4)
hSp = CONFIG.pxInt(6)
# Cached Translations
self._trLineCount = self.tr("Line: {0} ({1})")
@@ -3127,23 +3121,23 @@ class GuiDocEditFooter(QWidget):
# Assemble Layout
self.outerBox = QHBoxLayout()
self.outerBox.setSpacing(bSp)
self.outerBox.setSpacing(4)
self.outerBox.addWidget(self.statusIcon)
self.outerBox.addWidget(self.statusText)
self.outerBox.addStretch(1)
self.outerBox.addWidget(self.linesIcon)
self.outerBox.addWidget(self.linesText)
self.outerBox.addSpacing(hSp)
self.outerBox.addSpacing(6)
self.outerBox.addWidget(self.wordsIcon)
self.outerBox.addWidget(self.wordsText)
self.outerBox.setContentsMargins(mPx, mPx, mPx, mPx)
self.outerBox.setContentsMargins(8, 8, 8, 8)
self.setLayout(self.outerBox)
# Fix Margins and Size
# This is needed for high DPI systems. See issue #499.
self.setContentsMargins(0, 0, 0, 0)
self.setMinimumHeight(fPx + 2*mPx)
self.setMinimumHeight(fPx + 16)
# Fix the Colours
self.updateFont()
@@ -3226,12 +3220,13 @@ class GuiDocEditFooter(QWidget):
def updateLineCount(self, cursor: QTextCursor) -> None:
"""Update the line and document position counter."""
cPos = cursor.position() + 1
cLine = cursor.blockNumber() + 1
cCount = max(cursor.document().characterCount(), 1)
self.linesText.setText(
self._trLineCount.format(f"{cLine:n}", f"{100*cPos//cCount:d} %")
)
if document := cursor.document():
cPos = cursor.position() + 1
cLine = cursor.blockNumber() + 1
cCount = max(document.characterCount(), 1)
self.linesText.setText(
self._trLineCount.format(f"{cLine:n}", f"{100*cPos//cCount:d} %")
)
return
def updateWordCount(self, wCount: int, selection: bool) -> None:
+8 -8
View File
@@ -272,14 +272,14 @@ class GuiDocHighlighter(QSyntaxHighlighter):
"""Loop through all blocks and re-highlight those of a given
content type.
"""
qDoc = self.document()
nBlocks = qDoc.blockCount()
tStart = time()
for i in range(nBlocks):
block = qDoc.findBlockByNumber(i)
if block.userState() & cType > 0:
self.rehighlightBlock(block)
logger.debug("Document highlighted in %.3f ms" % (1000*(time() - tStart)))
if document := self.document():
nBlocks = document.blockCount()
tStart = time()
for i in range(nBlocks):
block = document.findBlockByNumber(i)
if block.userState() & cType > 0:
self.rehighlightBlock(block)
logger.debug("Document highlighted in %.3f ms" % (1000*(time() - tStart)))
return
##
+45 -50
View File
@@ -32,8 +32,8 @@ from enum import Enum
from PyQt6.QtCore import QPoint, Qt, QUrl, pyqtSignal, pyqtSlot
from PyQt6.QtGui import (
QAction, QCursor, QDesktopServices, QDragEnterEvent, QDragMoveEvent,
QDropEvent, QMouseEvent, QPalette, QResizeEvent, QTextCursor
QCursor, QDesktopServices, QDragEnterEvent, QDragMoveEvent, QDropEvent,
QMouseEvent, QPalette, QResizeEvent, QTextCursor
)
from PyQt6.QtWidgets import (
QApplication, QFrame, QHBoxLayout, QMenu, QTextBrowser, QToolButton,
@@ -41,7 +41,7 @@ from PyQt6.QtWidgets import (
)
from novelwriter import CONFIG, SHARED
from novelwriter.common import decodeMimeHandles, qtLambda
from novelwriter.common import decodeMimeHandles, qtAddAction, qtLambda
from novelwriter.constants import nwConst, nwStyles, nwUnicode
from novelwriter.enum import nwChange, nwDocAction, nwDocMode, nwItemType
from novelwriter.error import logException
@@ -79,7 +79,7 @@ class GuiDocViewer(QTextBrowser):
self._docTheme = TextDocumentTheme()
# Settings
self.setMinimumWidth(CONFIG.pxInt(300))
self.setMinimumWidth(300)
self.setAutoFillBackground(True)
self.setOpenLinks(False)
self.setOpenExternalLinks(False)
@@ -124,8 +124,7 @@ class GuiDocViewer(QTextBrowser):
@property
def scrollPosition(self) -> int:
"""Return the scrollbar position."""
vBar = self.verticalScrollBar()
if vBar.isVisible():
if (vBar := self.verticalScrollBar()) and vBar.isVisible():
return vBar.value()
return 0
@@ -163,12 +162,13 @@ class GuiDocViewer(QTextBrowser):
palette.setColor(QPalette.ColorRole.Text, syntax.text)
self.setPalette(palette)
palette = self.viewport().palette()
palette.setColor(QPalette.ColorRole.Base, syntax.back)
palette.setColor(QPalette.ColorRole.Text, syntax.text)
self.viewport().setPalette(palette)
self.docHeader.matchColours()
self.docFooter.matchColours()
if viewport := self.viewport():
palette = viewport.palette()
palette.setColor(QPalette.ColorRole.Base, syntax.back)
palette.setColor(QPalette.ColorRole.Text, syntax.text)
viewport.setPalette(palette)
self.docHeader.matchColours()
self.docFooter.matchColours()
# Update theme colours
self._docTheme.text = syntax.text
@@ -186,7 +186,8 @@ class GuiDocViewer(QTextBrowser):
self._docTheme.altdialog = syntax.dialA
# Set default text margins
self.document().setDocumentMargin(0)
if document := self.document():
document.setDocumentMargin(0)
# Scroll bars
if CONFIG.hideVScroll:
@@ -217,7 +218,9 @@ class GuiDocViewer(QTextBrowser):
logger.debug("Generating preview for item '%s'", tHandle)
QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
sPos = self.verticalScrollBar().value()
vBar = self.verticalScrollBar()
sPos = vBar.value() if vBar else 0
qDoc = ToQTextDocument(SHARED.project)
qDoc.setJustify(CONFIG.doJustify)
qDoc.setDialogHighlight(True)
@@ -252,9 +255,9 @@ class GuiDocViewer(QTextBrowser):
self.setDocument(qDoc.document)
self.setTabStopDistance(CONFIG.tabWidth)
if self._docHandle == tHandle:
if self._docHandle == tHandle and vBar:
# This is a refresh, so we set the scrollbar back to where it was
self.verticalScrollBar().setValue(sPos)
vBar.setValue(sPos)
self._docHandle = tHandle
SHARED.project.data.setLastHandle(tHandle, "viewer")
@@ -311,10 +314,10 @@ class GuiDocViewer(QTextBrowser):
cM = CONFIG.textMargin
vBar = self.verticalScrollBar()
sW = vBar.width() if vBar.isVisible() else 0
sW = vBar.width() if vBar and vBar.isVisible() else 0
hBar = self.horizontalScrollBar()
sH = hBar.height() if hBar.isVisible() else 0
sH = hBar.height() if hBar and hBar.isVisible() else 0
tM = cM
if CONFIG.textWidth > 0:
@@ -339,8 +342,7 @@ class GuiDocViewer(QTextBrowser):
def setScrollPosition(self, pos: int) -> None:
"""Set the scrollbar position."""
vBar = self.verticalScrollBar()
if vBar.isVisible():
if (vBar := self.verticalScrollBar()) and vBar.isVisible():
vBar.setValue(pos)
return
@@ -402,31 +404,27 @@ class GuiDocViewer(QTextBrowser):
ctxMenu = QMenu(self)
if userSelection:
mnuCopy = QAction(self.tr("Copy"), ctxMenu)
mnuCopy.triggered.connect(qtLambda(self.docAction, nwDocAction.COPY))
ctxMenu.addAction(mnuCopy)
action = qtAddAction(ctxMenu, self.tr("Copy"))
action.triggered.connect(qtLambda(self.docAction, nwDocAction.COPY))
ctxMenu.addSeparator()
mnuSelAll = QAction(self.tr("Select All"), ctxMenu)
mnuSelAll.triggered.connect(qtLambda(self.docAction, nwDocAction.SEL_ALL))
ctxMenu.addAction(mnuSelAll)
action = qtAddAction(ctxMenu, self.tr("Select All"))
action.triggered.connect(qtLambda(self.docAction, nwDocAction.SEL_ALL))
mnuSelWord = QAction(self.tr("Select Word"), ctxMenu)
mnuSelWord.triggered.connect(qtLambda(
action = qtAddAction(ctxMenu, self.tr("Select Word"))
action.triggered.connect(qtLambda(
self._makePosSelection, QTextCursor.SelectionType.WordUnderCursor, point
))
ctxMenu.addAction(mnuSelWord)
mnuSelPara = QAction(self.tr("Select Paragraph"), ctxMenu)
mnuSelPara.triggered.connect(qtLambda(
action = qtAddAction(ctxMenu, self.tr("Select Paragraph"))
action.triggered.connect(qtLambda(
self._makePosSelection, QTextCursor.SelectionType.BlockUnderCursor, point
))
ctxMenu.addAction(mnuSelPara)
# Open the context menu
ctxMenu.exec(self.viewport().mapToGlobal(point))
ctxMenu.deleteLater()
if viewport := self.viewport():
ctxMenu.exec(viewport.mapToGlobal(point))
ctxMenu.deleteLater()
return
@@ -452,7 +450,7 @@ class GuiDocViewer(QTextBrowser):
def dragEnterEvent(self, event: QDragEnterEvent) -> None:
"""Overload drag enter event to handle dragged items."""
if event.mimeData().hasFormat(nwConst.MIME_HANDLE):
if (data := event.mimeData()) and data.hasFormat(nwConst.MIME_HANDLE):
event.acceptProposedAction()
else:
super().dragEnterEvent(event)
@@ -460,7 +458,7 @@ class GuiDocViewer(QTextBrowser):
def dragMoveEvent(self, event: QDragMoveEvent) -> None:
"""Overload drag move event to handle dragged items."""
if event.mimeData().hasFormat(nwConst.MIME_HANDLE):
if (data := event.mimeData()) and data.hasFormat(nwConst.MIME_HANDLE):
event.acceptProposedAction()
else:
super().dragMoveEvent(event)
@@ -468,8 +466,8 @@ class GuiDocViewer(QTextBrowser):
def dropEvent(self, event: QDropEvent) -> None:
"""Overload drop event to handle dragged items."""
if event.mimeData().hasFormat(nwConst.MIME_HANDLE):
if handles := decodeMimeHandles(event.mimeData()):
if (data := event.mimeData()) and data.hasFormat(nwConst.MIME_HANDLE):
if handles := decodeMimeHandles(data):
if SHARED.project.tree.checkType(handles[0], nwItemType.FILE):
self.openDocumentRequest.emit(handles[0], nwDocMode.VIEW, "", True)
else:
@@ -640,7 +638,6 @@ class GuiDocViewHeader(QWidget):
iPx = SHARED.theme.baseIconHeight
iSz = SHARED.theme.baseIconSize
mPx = CONFIG.pxInt(4)
# Main Widget Settings
self.setAutoFillBackground(True)
@@ -692,9 +689,9 @@ class GuiDocViewHeader(QWidget):
self.outerBox.addWidget(self.outlineButton, 0)
self.outerBox.addWidget(self.backButton, 0)
self.outerBox.addWidget(self.forwardButton, 0)
self.outerBox.addSpacing(mPx)
self.outerBox.addSpacing(4)
self.outerBox.addWidget(self.itemTitle, 1)
self.outerBox.addSpacing(mPx)
self.outerBox.addSpacing(4)
self.outerBox.addWidget(self.editButton, 0)
self.outerBox.addWidget(self.refreshButton, 0)
self.outerBox.addWidget(self.closeButton, 0)
@@ -705,8 +702,8 @@ class GuiDocViewHeader(QWidget):
# Fix Margins and Size
# This is needed for high DPI systems. See issue #499.
self.setContentsMargins(0, 0, 0, 0)
self.outerBox.setContentsMargins(mPx, mPx, mPx, mPx)
self.setMinimumHeight(iPx + 2*mPx)
self.outerBox.setContentsMargins(4, 4, 4, 4)
self.setMinimumHeight(iPx + 8)
self.updateFont()
self.updateTheme()
@@ -747,7 +744,7 @@ class GuiDocViewHeader(QWidget):
minLevel = min(minLevel, level)
for title, text, level in entries[:30]:
indent = " "*(level - minLevel)
action = self.outlineMenu.addAction(f"{indent}{text}")
action = qtAddAction(self.outlineMenu, f"{indent}{text}")
action.triggered.connect(
lambda _, title=title: self.docViewer.navigateTo(f"#{tHandle}:{title}")
)
@@ -885,8 +882,6 @@ class GuiDocViewFooter(QWidget):
iPx = SHARED.theme.baseIconHeight
iSz = SHARED.theme.baseIconSize
hSp = CONFIG.pxInt(4)
mPx = CONFIG.pxInt(4)
# Main Widget Settings
self.setContentsMargins(0, 0, 0, 0)
@@ -923,14 +918,14 @@ class GuiDocViewFooter(QWidget):
self.outerBox.addStretch(1)
self.outerBox.addWidget(self.showComments, 0)
self.outerBox.addWidget(self.showSynopsis, 0)
self.outerBox.setSpacing(hSp)
self.outerBox.setSpacing(4)
self.setLayout(self.outerBox)
# Fix Margins and Size
# This is needed for high DPI systems. See issue #499.
self.setContentsMargins(0, 0, 0, 0)
self.outerBox.setContentsMargins(mPx, mPx, mPx, mPx)
self.setMinimumHeight(iPx + 2*mPx)
self.outerBox.setContentsMargins(4, 4, 4, 4)
self.setMinimumHeight(iPx + 8)
self.updateFont()
self.updateTheme()
+29 -31
View File
@@ -33,8 +33,8 @@ from PyQt6.QtWidgets import (
QTreeWidgetItem, QVBoxLayout, QWidget
)
from novelwriter import CONFIG, SHARED
from novelwriter.common import checkInt
from novelwriter import SHARED
from novelwriter.common import checkInt, qtAddAction
from novelwriter.constants import nwLabels, nwLists, nwStyles, trConst
from novelwriter.core.index import IndexHeading, IndexItem
from novelwriter.enum import nwChange, nwDocMode, nwItemClass
@@ -63,7 +63,7 @@ class GuiDocViewerPanel(QWidget):
self.optsMenu = QMenu(self)
self.aInactive = self.optsMenu.addAction(self.tr("Hide Inactive Tags"))
self.aInactive = qtAddAction(self.optsMenu, self.tr("Hide Inactive Tags"))
self.aInactive.setCheckable(True)
self.aInactive.toggled.connect(self._toggleHideInactive)
@@ -248,7 +248,6 @@ class _ViewPanelBackRefs(QTreeWidget):
iPx = SHARED.theme.baseIconHeight
iSz = SHARED.theme.baseIconSize
cMg = CONFIG.pxInt(6)
self.setHeaderLabels([self.tr("Document"), "", "", self.tr("First Heading")])
self.setIndentation(0)
@@ -257,16 +256,16 @@ class _ViewPanelBackRefs(QTreeWidget):
self.setFrameStyle(QFrame.Shape.NoFrame)
# Set Header Sizes
treeHeader = self.header()
treeHeader.setStretchLastSection(True)
treeHeader.setMinimumSectionSize(iPx + cMg) # See Issue #1627
treeHeader.setSectionResizeMode(self.C_DOC, QtHeaderToContents)
treeHeader.setSectionResizeMode(self.C_EDIT, QtHeaderFixed)
treeHeader.setSectionResizeMode(self.C_VIEW, QtHeaderFixed)
treeHeader.setSectionResizeMode(self.C_TITLE, QtHeaderToContents)
treeHeader.resizeSection(self.C_EDIT, iPx + cMg)
treeHeader.resizeSection(self.C_VIEW, iPx + cMg)
treeHeader.setSectionsMovable(False)
if header := self.header():
header.setStretchLastSection(True)
header.setMinimumSectionSize(iPx + 6) # See Issue #1627
header.setSectionResizeMode(self.C_DOC, QtHeaderToContents)
header.setSectionResizeMode(self.C_EDIT, QtHeaderFixed)
header.setSectionResizeMode(self.C_VIEW, QtHeaderFixed)
header.setSectionResizeMode(self.C_TITLE, QtHeaderToContents)
header.resizeSection(self.C_EDIT, iPx + 6)
header.resizeSection(self.C_VIEW, iPx + 6)
header.setSectionsMovable(False)
# Cache Icons Locally
self._editIcon = SHARED.theme.getIcon("edit", "green")
@@ -385,7 +384,6 @@ class _ViewPanelKeyWords(QTreeWidget):
iPx = SHARED.theme.baseIconHeight
iSz = SHARED.theme.baseIconSize
cMg = CONFIG.pxInt(6)
self.setHeaderLabels([
self.tr("Tag"), "", "", self.tr("Importance"), self.tr("Document"),
@@ -401,14 +399,14 @@ class _ViewPanelKeyWords(QTreeWidget):
self.sortByColumn(self.C_NAME, Qt.SortOrder.AscendingOrder)
# Set Header Sizes
treeHeader = self.header()
treeHeader.setStretchLastSection(True)
treeHeader.setMinimumSectionSize(iPx + cMg) # See Issue #1627
treeHeader.setSectionResizeMode(self.C_EDIT, QtHeaderFixed)
treeHeader.setSectionResizeMode(self.C_VIEW, QtHeaderFixed)
treeHeader.resizeSection(self.C_EDIT, iPx + cMg)
treeHeader.resizeSection(self.C_VIEW, iPx + cMg)
treeHeader.setSectionsMovable(False)
if header := self.header():
header.setStretchLastSection(True)
header.setMinimumSectionSize(iPx + 6) # See Issue #1627
header.setSectionResizeMode(self.C_EDIT, QtHeaderFixed)
header.setSectionResizeMode(self.C_VIEW, QtHeaderFixed)
header.resizeSection(self.C_EDIT, iPx + 6)
header.resizeSection(self.C_VIEW, iPx + 6)
header.setSectionsMovable(False)
# Cache Icons Locally
self.updateTheme()
@@ -482,19 +480,19 @@ class _ViewPanelKeyWords(QTreeWidget):
def setColumnWidths(self, widths: list[int]) -> None:
"""Set the column widths."""
if isinstance(widths, list) and len(widths) >= 4:
self.setColumnWidth(self.C_NAME, CONFIG.pxInt(checkInt(widths[0], 100)))
self.setColumnWidth(self.C_IMPORT, CONFIG.pxInt(checkInt(widths[1], 100)))
self.setColumnWidth(self.C_DOC, CONFIG.pxInt(checkInt(widths[2], 100)))
self.setColumnWidth(self.C_TITLE, CONFIG.pxInt(checkInt(widths[3], 100)))
self.setColumnWidth(self.C_NAME, checkInt(widths[0], 100))
self.setColumnWidth(self.C_IMPORT, checkInt(widths[1], 100))
self.setColumnWidth(self.C_DOC, checkInt(widths[2], 100))
self.setColumnWidth(self.C_TITLE, checkInt(widths[3], 100))
return
def getColumnWidths(self) -> list[int]:
"""Get the widths of the user-adjustable columns."""
return [
CONFIG.rpxInt(self.columnWidth(self.C_NAME)),
CONFIG.rpxInt(self.columnWidth(self.C_IMPORT)),
CONFIG.rpxInt(self.columnWidth(self.C_DOC)),
CONFIG.rpxInt(self.columnWidth(self.C_TITLE)),
self.columnWidth(self.C_NAME),
self.columnWidth(self.C_IMPORT),
self.columnWidth(self.C_DOC),
self.columnWidth(self.C_TITLE),
]
##
+4 -7
View File
@@ -30,7 +30,7 @@ from enum import Enum
from PyQt6.QtCore import pyqtSlot
from PyQt6.QtWidgets import QGridLayout, QLabel, QWidget
from novelwriter import CONFIG, SHARED
from novelwriter import SHARED
from novelwriter.common import elide
from novelwriter.constants import nwLabels, nwStats, trConst
from novelwriter.enum import nwChange
@@ -53,9 +53,6 @@ class GuiItemDetails(QWidget):
self._handle = None
# Sizes
hSp = CONFIG.pxInt(6)
vSp = CONFIG.pxInt(1)
mPx = CONFIG.pxInt(6)
fPt = SHARED.theme.fontPointSize
fntLabel = self.font()
@@ -176,9 +173,9 @@ class GuiItemDetails(QWidget):
self.mainBox.setColumnStretch(3, 0)
self.mainBox.setColumnStretch(4, 0)
self.mainBox.setHorizontalSpacing(hSp)
self.mainBox.setVerticalSpacing(vSp)
self.mainBox.setContentsMargins(mPx, mPx, mPx, mPx)
self.mainBox.setHorizontalSpacing(6)
self.mainBox.setVerticalSpacing(1)
self.mainBox.setContentsMargins(6, 6, 6, 6)
self.setLayout(self.mainBox)
+136 -136
View File
@@ -33,7 +33,7 @@ from PyQt6.QtGui import QAction
from PyQt6.QtWidgets import QMenuBar
from novelwriter import CONFIG, SHARED
from novelwriter.common import openExternalPath, qtLambda
from novelwriter.common import openExternalPath, qtAddAction, qtAddMenu, qtLambda
from novelwriter.constants import (
nwConst, nwKeyWords, nwLabels, nwShortcode, nwStats, nwStyles, nwUnicode,
trConst
@@ -128,21 +128,21 @@ class GuiMainMenu(QMenuBar):
def _buildProjectMenu(self) -> None:
"""Assemble the Project menu."""
# Project
self.projMenu = self.addMenu(self.tr("&Project"))
self.projMenu = qtAddMenu(self, self.tr("&Project"))
# Project > Create or Open Project
self.aOpenProject = self.projMenu.addAction(self.tr("Create or Open Project"))
self.aOpenProject = qtAddAction(self.projMenu, self.tr("Create or Open Project"))
self.aOpenProject.setShortcut("Ctrl+Shift+O")
self.aOpenProject.triggered.connect(self.mainGui.showWelcomeDialog)
# Project > Save Project
self.aSaveProject = self.projMenu.addAction(self.tr("Save Project"))
self.aSaveProject = qtAddAction(self.projMenu, self.tr("Save Project"))
self.aSaveProject.setShortcut("Ctrl+Shift+S")
self.aSaveProject.triggered.connect(qtLambda(self.mainGui.saveProject))
self.mainGui.addAction(self.aSaveProject)
# Project > Close Project
self.aCloseProject = self.projMenu.addAction(self.tr("Close Project"))
self.aCloseProject = qtAddAction(self.projMenu, self.tr("Close Project"))
self.aCloseProject.setShortcut("Ctrl+Shift+W")
self.aCloseProject.triggered.connect(qtLambda(self.mainGui.closeProject, False))
@@ -150,12 +150,12 @@ class GuiMainMenu(QMenuBar):
self.projMenu.addSeparator()
# Project > Project Settings
self.aProjectSettings = self.projMenu.addAction(self.tr("Project Settings"))
self.aProjectSettings = qtAddAction(self.projMenu, self.tr("Project Settings"))
self.aProjectSettings.setShortcut("Ctrl+Shift+,")
self.aProjectSettings.triggered.connect(self.mainGui.showProjectSettingsDialog)
# Project > Novel Details
self.aNovelDetails = self.projMenu.addAction(self.tr("Novel Details"))
self.aNovelDetails = qtAddAction(self.projMenu, self.tr("Novel Details"))
self.aNovelDetails.setShortcut("Shift+F6")
self.aNovelDetails.triggered.connect(self.mainGui.showNovelDetailsDialog)
@@ -163,16 +163,16 @@ class GuiMainMenu(QMenuBar):
self.projMenu.addSeparator()
# Project > Edit
self.aRenameItem = self.projMenu.addAction(self.tr("Rename Item"))
self.aRenameItem = qtAddAction(self.projMenu, self.tr("Rename Item"))
self.aRenameItem.setShortcut("F2")
# Project > Delete
self.aDeleteItem = self.projMenu.addAction(self.tr("Delete Item"))
self.aDeleteItem = qtAddAction(self.projMenu, self.tr("Delete Item"))
self.aDeleteItem.setShortcut("Del")
self.aDeleteItem.setShortcutContext(Qt.ShortcutContext.WidgetShortcut)
# Project > Empty Trash
self.aEmptyTrash = self.projMenu.addAction(self.tr("Empty Trash"))
self.aEmptyTrash = qtAddAction(self.projMenu, self.tr("Empty Trash"))
self.mainGui.projView.connectMenuActions(
self.aRenameItem, self.aDeleteItem, self.aEmptyTrash
@@ -182,7 +182,7 @@ class GuiMainMenu(QMenuBar):
self.projMenu.addSeparator()
# Project > Exit
self.aExitNW = self.projMenu.addAction(self.tr("Exit"))
self.aExitNW = qtAddAction(self.projMenu, self.tr("Exit"))
self.aExitNW.setShortcut("Ctrl+Q")
self.aExitNW.setMenuRole(QAction.MenuRole.QuitRole)
self.aExitNW.triggered.connect(qtLambda(self.mainGui.closeMain))
@@ -193,21 +193,21 @@ class GuiMainMenu(QMenuBar):
def _buildDocumentMenu(self) -> None:
"""Assemble the Document menu."""
# Document
self.docuMenu = self.addMenu(self.tr("&Document"))
self.docuMenu = qtAddMenu(self, self.tr("&Document"))
# Document > Open
self.aOpenDoc = self.docuMenu.addAction(self.tr("Open Document"))
self.aOpenDoc = qtAddAction(self.docuMenu, self.tr("Open Document"))
self.aOpenDoc.setShortcut("Ctrl+O")
self.aOpenDoc.triggered.connect(self.mainGui.openSelectedItem)
# Document > Save
self.aSaveDoc = self.docuMenu.addAction(self.tr("Save Document"))
self.aSaveDoc = qtAddAction(self.docuMenu, self.tr("Save Document"))
self.aSaveDoc.setShortcut("Ctrl+S")
self.aSaveDoc.triggered.connect(self.mainGui.forceSaveDocument)
self.mainGui.addAction(self.aSaveDoc)
# Document > Close
self.aCloseDoc = self.docuMenu.addAction(self.tr("Close Document"))
self.aCloseDoc = qtAddAction(self.docuMenu, self.tr("Close Document"))
self.aCloseDoc.setShortcut("Ctrl+W")
self.aCloseDoc.triggered.connect(self.mainGui.closeDocEditor)
self.mainGui.addAction(self.aCloseDoc)
@@ -216,12 +216,12 @@ class GuiMainMenu(QMenuBar):
self.docuMenu.addSeparator()
# Document > Preview
self.aViewDoc = self.docuMenu.addAction(self.tr("View Document"))
self.aViewDoc = qtAddAction(self.docuMenu, self.tr("View Document"))
self.aViewDoc.setShortcut("Ctrl+R")
self.aViewDoc.triggered.connect(qtLambda(self.mainGui.viewDocument, None))
# Document > Close Preview
self.aCloseView = self.docuMenu.addAction(self.tr("Close Document View"))
self.aCloseView = qtAddAction(self.docuMenu, self.tr("Close Document View"))
self.aCloseView.setShortcut("Ctrl+Shift+R")
self.aCloseView.triggered.connect(self.mainGui.closeDocViewer)
@@ -229,11 +229,11 @@ class GuiMainMenu(QMenuBar):
self.docuMenu.addSeparator()
# Document > Show File Details
self.aFileDetails = self.docuMenu.addAction(self.tr("Show File Details"))
self.aFileDetails = qtAddAction(self.docuMenu, self.tr("Show File Details"))
self.aFileDetails.triggered.connect(qtLambda(self.mainGui.docEditor.revealLocation))
# Document > Import From File
self.aImportFile = self.docuMenu.addAction(self.tr("Import Text from File"))
self.aImportFile = qtAddAction(self.docuMenu, self.tr("Import Text from File"))
self.aImportFile.triggered.connect(qtLambda(self.mainGui.importDocument))
return
@@ -241,10 +241,10 @@ class GuiMainMenu(QMenuBar):
def _buildEditMenu(self) -> None:
"""Assemble the Edit menu."""
# Edit
self.editMenu = self.addMenu(self.tr("&Edit"))
self.editMenu = qtAddMenu(self, self.tr("&Edit"))
# Edit > Undo
self.aEditUndo = self.editMenu.addAction(self.tr("Undo"))
self.aEditUndo = qtAddAction(self.editMenu, self.tr("Undo"))
self.aEditUndo.setShortcut("Ctrl+Z")
self.aEditUndo.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.UNDO)
@@ -252,7 +252,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aEditUndo)
# Edit > Redo
self.aEditRedo = self.editMenu.addAction(self.tr("Redo"))
self.aEditRedo = qtAddAction(self.editMenu, self.tr("Redo"))
self.aEditRedo.setShortcut("Ctrl+Y")
self.aEditRedo.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.REDO)
@@ -263,7 +263,7 @@ class GuiMainMenu(QMenuBar):
self.editMenu.addSeparator()
# Edit > Cut
self.aEditCut = self.editMenu.addAction(self.tr("Cut"))
self.aEditCut = qtAddAction(self.editMenu, self.tr("Cut"))
self.aEditCut.setShortcut("Ctrl+X")
self.aEditCut.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.CUT)
@@ -271,7 +271,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aEditCut)
# Edit > Copy
self.aEditCopy = self.editMenu.addAction(self.tr("Copy"))
self.aEditCopy = qtAddAction(self.editMenu, self.tr("Copy"))
self.aEditCopy.setShortcut("Ctrl+C")
self.aEditCopy.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.COPY)
@@ -279,7 +279,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aEditCopy)
# Edit > Paste
self.aEditPaste = self.editMenu.addAction(self.tr("Paste"))
self.aEditPaste = qtAddAction(self.editMenu, self.tr("Paste"))
self.aEditPaste.setShortcut("Ctrl+V")
self.aEditPaste.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.PASTE)
@@ -290,7 +290,7 @@ class GuiMainMenu(QMenuBar):
self.editMenu.addSeparator()
# Edit > Select All
self.aSelectAll = self.editMenu.addAction(self.tr("Select All"))
self.aSelectAll = qtAddAction(self.editMenu, self.tr("Select All"))
self.aSelectAll.setShortcut("Ctrl+A")
self.aSelectAll.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.SEL_ALL)
@@ -298,7 +298,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aSelectAll)
# Edit > Select Paragraph
self.aSelectPar = self.editMenu.addAction(self.tr("Select Paragraph"))
self.aSelectPar = qtAddAction(self.editMenu, self.tr("Select Paragraph"))
self.aSelectPar.setShortcut("Ctrl+Shift+A")
self.aSelectPar.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.SEL_PARA)
@@ -310,24 +310,24 @@ class GuiMainMenu(QMenuBar):
def _buildViewMenu(self) -> None:
"""Assemble the View menu."""
# View
self.viewMenu = self.addMenu(self.tr("&View"))
self.viewMenu = qtAddMenu(self, self.tr("&View"))
# View > TreeView
self.aFocusTree = self.viewMenu.addAction(self.tr("Go to Tree View"))
self.aFocusTree = qtAddAction(self.viewMenu, self.tr("Go to Tree View"))
self.aFocusTree.setShortcut("Ctrl+T")
self.aFocusTree.triggered.connect(
lambda: self.requestFocusChange.emit(nwFocus.TREE)
)
# View > Document Editor
self.aFocusDocument = self.viewMenu.addAction(self.tr("Go to Document"))
self.aFocusDocument = qtAddAction(self.viewMenu, 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 = qtAddAction(self.viewMenu, self.tr("Go to Outline"))
self.aFocusOutline.setShortcut("Ctrl+Shift+T")
self.aFocusOutline.triggered.connect(
lambda: self.requestFocusChange.emit(nwFocus.OUTLINE)
@@ -337,14 +337,14 @@ class GuiMainMenu(QMenuBar):
self.viewMenu.addSeparator()
# View > Go Backward
self.aViewPrev = self.viewMenu.addAction(self.tr("Navigate Backward"))
self.aViewPrev = qtAddAction(self.viewMenu, self.tr("Navigate Backward"))
self.aViewPrev.setShortcut("Alt+Left")
self.aViewPrev.setShortcutContext(Qt.ShortcutContext.WidgetShortcut)
self.aViewPrev.triggered.connect(self.mainGui.docViewer.navBackward)
self.mainGui.docViewer.addAction(self.aViewPrev)
# View > Go Forward
self.aViewNext = self.viewMenu.addAction(self.tr("Navigate Forward"))
self.aViewNext = qtAddAction(self.viewMenu, self.tr("Navigate Forward"))
self.aViewNext.setShortcut("Alt+Right")
self.aViewNext.setShortcutContext(Qt.ShortcutContext.WidgetShortcut)
self.aViewNext.triggered.connect(self.mainGui.docViewer.navForward)
@@ -354,13 +354,13 @@ class GuiMainMenu(QMenuBar):
self.viewMenu.addSeparator()
# View > Focus Mode
self.aFocusMode = self.viewMenu.addAction(self.tr("Focus Mode"))
self.aFocusMode = qtAddAction(self.viewMenu, self.tr("Focus Mode"))
self.aFocusMode.setShortcut("F8")
self.aFocusMode.triggered.connect(self.mainGui.toggleFocusMode)
self.mainGui.addAction(self.aFocusMode)
# View > Toggle Full Screen
self.aFullScreen = self.viewMenu.addAction(self.tr("Full Screen Mode"))
self.aFullScreen = qtAddAction(self.viewMenu, self.tr("Full Screen Mode"))
self.aFullScreen.setShortcut("F11")
self.aFullScreen.triggered.connect(self.mainGui.toggleFullScreenMode)
self.mainGui.addAction(self.aFullScreen)
@@ -370,13 +370,13 @@ class GuiMainMenu(QMenuBar):
def _buildInsertMenu(self) -> None:
"""Assemble the Insert menu."""
# Insert
self.insMenu = self.addMenu(self.tr("&Insert"))
self.insMenu = qtAddMenu(self, self.tr("&Insert"))
# Insert > Dashes and Dots
self.mInsDashes = self.insMenu.addMenu(self.tr("Dashes"))
self.mInsDashes = qtAddMenu(self.insMenu, self.tr("Dashes"))
# Insert > Short Dash
self.aInsENDash = self.mInsDashes.addAction(self.tr("Short Dash"))
self.aInsENDash = qtAddAction(self.mInsDashes, self.tr("Short Dash"))
self.aInsENDash.setShortcut("Ctrl+K, -")
self.aInsENDash.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_ENDASH)
@@ -384,7 +384,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsENDash)
# Insert > Long Dash
self.aInsEMDash = self.mInsDashes.addAction(self.tr("Long Dash"))
self.aInsEMDash = qtAddAction(self.mInsDashes, self.tr("Long Dash"))
self.aInsEMDash.setShortcut("Ctrl+K, _")
self.aInsEMDash.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_EMDASH)
@@ -392,7 +392,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsEMDash)
# Insert > Long Dash
self.aInsHorBar = self.mInsDashes.addAction(self.tr("Horizontal Bar"))
self.aInsHorBar = qtAddAction(self.mInsDashes, self.tr("Horizontal Bar"))
self.aInsHorBar.setShortcut("Ctrl+K, Ctrl+_")
self.aInsHorBar.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_HBAR)
@@ -400,7 +400,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsHorBar)
# Insert > Figure Dash
self.aInsFigDash = self.mInsDashes.addAction(self.tr("Figure Dash"))
self.aInsFigDash = qtAddAction(self.mInsDashes, self.tr("Figure Dash"))
self.aInsFigDash.setShortcut("Ctrl+K, ~")
self.aInsFigDash.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_FGDASH)
@@ -408,10 +408,10 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsFigDash)
# Insert > Quote Marks
self.mInsQuotes = self.insMenu.addMenu(self.tr("Quote Marks"))
self.mInsQuotes = qtAddMenu(self.insMenu, self.tr("Quote Marks"))
# Insert > Left Single Quote
self.aInsQuoteLS = self.mInsQuotes.addAction(self.tr("Left Single Quote"))
self.aInsQuoteLS = qtAddAction(self.mInsQuotes, self.tr("Left Single Quote"))
self.aInsQuoteLS.setShortcut("Ctrl+K, 1")
self.aInsQuoteLS.triggered.connect(
lambda: self.requestDocInsert.emit(nwDocInsert.QUOTE_LS)
@@ -419,7 +419,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsQuoteLS)
# Insert > Right Single Quote
self.aInsQuoteRS = self.mInsQuotes.addAction(self.tr("Right Single Quote"))
self.aInsQuoteRS = qtAddAction(self.mInsQuotes, self.tr("Right Single Quote"))
self.aInsQuoteRS.setShortcut("Ctrl+K, 2")
self.aInsQuoteRS.triggered.connect(
lambda: self.requestDocInsert.emit(nwDocInsert.QUOTE_RS)
@@ -427,7 +427,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsQuoteRS)
# Insert > Left Double Quote
self.aInsQuoteLD = self.mInsQuotes.addAction(self.tr("Left Double Quote"))
self.aInsQuoteLD = qtAddAction(self.mInsQuotes, self.tr("Left Double Quote"))
self.aInsQuoteLD.setShortcut("Ctrl+K, 3")
self.aInsQuoteLD.triggered.connect(
lambda: self.requestDocInsert.emit(nwDocInsert.QUOTE_LD)
@@ -435,7 +435,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsQuoteLD)
# Insert > Right Double Quote
self.aInsQuoteRD = self.mInsQuotes.addAction(self.tr("Right Double Quote"))
self.aInsQuoteRD = qtAddAction(self.mInsQuotes, self.tr("Right Double Quote"))
self.aInsQuoteRD.setShortcut("Ctrl+K, 4")
self.aInsQuoteRD.triggered.connect(
lambda: self.requestDocInsert.emit(nwDocInsert.QUOTE_RD)
@@ -443,7 +443,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsQuoteRD)
# Insert > Alternative Apostrophe
self.aInsMSApos = self.mInsQuotes.addAction(self.tr("Alternative Apostrophe"))
self.aInsMSApos = qtAddAction(self.mInsQuotes, self.tr("Alternative Apostrophe"))
self.aInsMSApos.setShortcut("Ctrl+K, '")
self.aInsMSApos.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_MAPOS)
@@ -451,10 +451,10 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsMSApos)
# Insert > Symbols
self.mInsPunct = self.insMenu.addMenu(self.tr("General Punctuation"))
self.mInsPunct = qtAddMenu(self.insMenu, self.tr("General Punctuation"))
# Insert > Ellipsis
self.aInsEllipsis = self.mInsPunct.addAction(self.tr("Ellipsis"))
self.aInsEllipsis = qtAddAction(self.mInsPunct, self.tr("Ellipsis"))
self.aInsEllipsis.setShortcut("Ctrl+K, .")
self.aInsEllipsis.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_HELLIP)
@@ -462,7 +462,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsEllipsis)
# Insert > Prime
self.aInsPrime = self.mInsPunct.addAction(self.tr("Prime"))
self.aInsPrime = qtAddAction(self.mInsPunct, self.tr("Prime"))
self.aInsPrime.setShortcut("Ctrl+K, Ctrl+'")
self.aInsPrime.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_PRIME)
@@ -470,7 +470,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsPrime)
# Insert > Double Prime
self.aInsDPrime = self.mInsPunct.addAction(self.tr("Double Prime"))
self.aInsDPrime = qtAddAction(self.mInsPunct, self.tr("Double Prime"))
self.aInsDPrime.setShortcut("Ctrl+K, Ctrl+\"")
self.aInsDPrime.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_DPRIME)
@@ -478,10 +478,10 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsDPrime)
# Insert > White Spaces
self.mInsSpace = self.insMenu.addMenu(self.tr("White Spaces"))
self.mInsSpace = qtAddMenu(self.insMenu, self.tr("White Spaces"))
# Insert > Non-Breaking Space
self.aInsNBSpace = self.mInsSpace.addAction(self.tr("Non-Breaking Space"))
self.aInsNBSpace = qtAddAction(self.mInsSpace, self.tr("Non-Breaking Space"))
self.aInsNBSpace.setShortcut("Ctrl+K, Space")
self.aInsNBSpace.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_NBSP)
@@ -489,7 +489,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsNBSpace)
# Insert > Thin Space
self.aInsThinSpace = self.mInsSpace.addAction(self.tr("Thin Space"))
self.aInsThinSpace = qtAddAction(self.mInsSpace, self.tr("Thin Space"))
self.aInsThinSpace.setShortcut("Ctrl+K, Shift+Space")
self.aInsThinSpace.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_THSP)
@@ -497,7 +497,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsThinSpace)
# Insert > Thin Non-Breaking Space
self.aInsThinNBSpace = self.mInsSpace.addAction(self.tr("Thin Non-Breaking Space"))
self.aInsThinNBSpace = qtAddAction(self.mInsSpace, self.tr("Thin Non-Breaking Space"))
self.aInsThinNBSpace.setShortcut("Ctrl+K, Ctrl+Space")
self.aInsThinNBSpace.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_THNBSP)
@@ -505,10 +505,10 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsThinNBSpace)
# Insert > Symbols
self.mInsSymbol = self.insMenu.addMenu(self.tr("Other Symbols"))
self.mInsSymbol = qtAddMenu(self.insMenu, self.tr("Other Symbols"))
# Insert > List Bullet
self.aInsBullet = self.mInsSymbol.addAction(self.tr("List Bullet"))
self.aInsBullet = qtAddAction(self.mInsSymbol, self.tr("List Bullet"))
self.aInsBullet.setShortcut("Ctrl+K, *")
self.aInsBullet.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_BULL)
@@ -516,7 +516,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsBullet)
# Insert > Hyphen Bullet
self.aInsHyBull = self.mInsSymbol.addAction(self.tr("Hyphen Bullet"))
self.aInsHyBull = qtAddAction(self.mInsSymbol, self.tr("Hyphen Bullet"))
self.aInsHyBull.setShortcut("Ctrl+K, Ctrl+-")
self.aInsHyBull.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_HYBULL)
@@ -524,7 +524,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsHyBull)
# Insert > Flower Mark
self.aInsFlower = self.mInsSymbol.addAction(self.tr("Flower Mark"))
self.aInsFlower = qtAddAction(self.mInsSymbol, self.tr("Flower Mark"))
self.aInsFlower.setShortcut("Ctrl+K, Ctrl+*")
self.aInsFlower.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_FLOWER)
@@ -532,7 +532,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsFlower)
# Insert > Per Mille
self.aInsPerMille = self.mInsSymbol.addAction(self.tr("Per Mille"))
self.aInsPerMille = qtAddAction(self.mInsSymbol, self.tr("Per Mille"))
self.aInsPerMille.setShortcut("Ctrl+K, %")
self.aInsPerMille.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_PERMIL)
@@ -540,7 +540,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsPerMille)
# Insert > Degree Symbol
self.aInsDegree = self.mInsSymbol.addAction(self.tr("Degree Symbol"))
self.aInsDegree = qtAddAction(self.mInsSymbol, self.tr("Degree Symbol"))
self.aInsDegree.setShortcut("Ctrl+K, Ctrl+O")
self.aInsDegree.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_DEGREE)
@@ -548,7 +548,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsDegree)
# Insert > Minus Sign
self.aInsMinus = self.mInsSymbol.addAction(self.tr("Minus Sign"))
self.aInsMinus = qtAddAction(self.mInsSymbol, self.tr("Minus Sign"))
self.aInsMinus.setShortcut("Ctrl+K, Ctrl+M")
self.aInsMinus.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_MINUS)
@@ -556,7 +556,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsMinus)
# Insert > Times Sign
self.aInsTimes = self.mInsSymbol.addAction(self.tr("Times Sign"))
self.aInsTimes = qtAddAction(self.mInsSymbol, self.tr("Times Sign"))
self.aInsTimes.setShortcut("Ctrl+K, Ctrl+X")
self.aInsTimes.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_TIMES)
@@ -564,7 +564,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsTimes)
# Insert > Division
self.aInsDivide = self.mInsSymbol.addAction(self.tr("Division Sign"))
self.aInsDivide = qtAddAction(self.mInsSymbol, self.tr("Division Sign"))
self.aInsDivide.setShortcut("Ctrl+K, Ctrl+D")
self.aInsDivide.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_DIVIDE)
@@ -572,18 +572,18 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsDivide)
# Insert > Tags and References
self.mInsKeywords = self.insMenu.addMenu(self.tr("Tags and References"))
self.mInsKeywords = qtAddMenu(self.insMenu, self.tr("Tags and References"))
for key in nwKeyWords.ALL_KEYS:
action = self.mInsKeywords.addAction(trConst(nwLabels.KEY_NAME[key]))
action = qtAddAction(self.mInsKeywords, trConst(nwLabels.KEY_NAME[key]))
action.setShortcut(nwLabels.KEY_SHORTCUT[key])
action.triggered.connect(qtLambda(self.requestDocKeyWordInsert.emit, key))
self.mainGui.addAction(action)
# Insert > Special Comments
self.mInsComments = self.insMenu.addMenu(self.tr("Special Comments"))
self.mInsComments = qtAddMenu(self.insMenu, self.tr("Special Comments"))
# Insert > Synopsis Comment
self.aInsSynopsis = self.mInsComments.addAction(self.tr("Synopsis Comment"))
self.aInsSynopsis = qtAddAction(self.mInsComments, self.tr("Synopsis Comment"))
self.aInsSynopsis.setShortcut("Ctrl+K, S")
self.aInsSynopsis.triggered.connect(
lambda: self.requestDocInsert.emit(nwDocInsert.SYNOPSIS)
@@ -591,7 +591,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsSynopsis)
# Insert > Short Description Comment
self.aInsShort = self.mInsComments.addAction(self.tr("Short Description Comment"))
self.aInsShort = qtAddAction(self.mInsComments, self.tr("Short Description Comment"))
self.aInsShort.setShortcut("Ctrl+K, H")
self.aInsShort.triggered.connect(
lambda: self.requestDocInsert.emit(nwDocInsert.SHORT)
@@ -599,47 +599,47 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aInsShort)
# Insert > Word/Character Count
self.mInsField = self.insMenu.addMenu(self.tr("Word/Character Count"))
self.mInsField = qtAddMenu(self.insMenu, self.tr("Word/Character Count"))
for field in nwStats.ALL_FIELDS:
value = nwShortcode.FIELD_VALUE.format(field)
action = self.mInsField.addAction(trConst(nwLabels.STATS_NAME[field]))
action = qtAddAction(self.mInsField, trConst(nwLabels.STATS_NAME[field]))
action.triggered.connect(qtLambda(self.requestDocInsertText.emit, value))
# Insert > Breaks and Vertical Space
self.mInsBreaks = self.insMenu.addMenu(self.tr("Breaks and Vertical Space"))
self.mInsBreaks = qtAddMenu(self.insMenu, self.tr("Breaks and Vertical Space"))
# Insert > New Page
self.aInsNewPage = self.mInsBreaks.addAction(self.tr("Page Break"))
self.aInsNewPage = qtAddAction(self.mInsBreaks, self.tr("Page Break"))
self.aInsNewPage.triggered.connect(
lambda: self.requestDocInsert.emit(nwDocInsert.NEW_PAGE)
)
# Insert > Forced Line Break
self.aInsLineBreak = self.mInsBreaks.addAction(self.tr("Forced Line Break"))
self.aInsLineBreak = qtAddAction(self.mInsBreaks, self.tr("Forced Line Break"))
self.aInsLineBreak.triggered.connect(
lambda: self.requestDocInsert.emit(nwDocInsert.LINE_BRK)
)
# Insert > Vertical Space (Single)
self.aInsVSpaceS = self.mInsBreaks.addAction(self.tr("Vertical Space (Single)"))
self.aInsVSpaceS = qtAddAction(self.mInsBreaks, self.tr("Vertical Space (Single)"))
self.aInsVSpaceS.triggered.connect(
lambda: self.requestDocInsert.emit(nwDocInsert.VSPACE_S)
)
# Insert > Vertical Space (Multi)
self.aInsVSpaceM = self.mInsBreaks.addAction(self.tr("Vertical Space (Multi)"))
self.aInsVSpaceM = qtAddAction(self.mInsBreaks, self.tr("Vertical Space (Multi)"))
self.aInsVSpaceM.triggered.connect(
lambda: self.requestDocInsert.emit(nwDocInsert.VSPACE_M)
)
# Insert > Placeholder Text
self.aLipsumText = self.insMenu.addAction(self.tr("Placeholder Text"))
self.aLipsumText = qtAddAction(self.insMenu, self.tr("Placeholder Text"))
self.aLipsumText.triggered.connect(
lambda: self.requestDocInsert.emit(nwDocInsert.LIPSUM)
)
# Insert > Footnote
self.aFootnote = self.insMenu.addAction(self.tr("Footnote"))
self.aFootnote = qtAddAction(self.insMenu, self.tr("Footnote"))
self.aFootnote.triggered.connect(
lambda: self.requestDocInsert.emit(nwDocInsert.FOOTNOTE)
)
@@ -649,10 +649,10 @@ class GuiMainMenu(QMenuBar):
def _buildFormatMenu(self) -> None:
"""Assemble the Format menu."""
# Format
self.fmtMenu = self.addMenu(self.tr("&Format"))
self.fmtMenu = qtAddMenu(self, self.tr("&Format"))
# Format > Bold
self.aFmtBold = self.fmtMenu.addAction(self.tr("Bold"))
self.aFmtBold = qtAddAction(self.fmtMenu, self.tr("Bold"))
self.aFmtBold.setShortcut("Ctrl+B")
self.aFmtBold.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.MD_BOLD)
@@ -660,7 +660,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aFmtBold)
# Format > Italic
self.aFmtItalic = self.fmtMenu.addAction(self.tr("Italic"))
self.aFmtItalic = qtAddAction(self.fmtMenu, self.tr("Italic"))
self.aFmtItalic.setShortcut("Ctrl+I")
self.aFmtItalic.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.MD_ITALIC)
@@ -668,7 +668,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aFmtItalic)
# Format > Strikethrough
self.aFmtStrike = self.fmtMenu.addAction(self.tr("Strikethrough"))
self.aFmtStrike = qtAddAction(self.fmtMenu, self.tr("Strikethrough"))
self.aFmtStrike.setShortcut("Ctrl+D")
self.aFmtStrike.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.MD_STRIKE)
@@ -679,7 +679,7 @@ class GuiMainMenu(QMenuBar):
self.fmtMenu.addSeparator()
# Format > Double Quotes
self.aFmtDQuote = self.fmtMenu.addAction(self.tr("Wrap Double Quotes"))
self.aFmtDQuote = qtAddAction(self.fmtMenu, self.tr("Wrap Double Quotes"))
self.aFmtDQuote.setShortcut("Ctrl+\"")
self.aFmtDQuote.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.D_QUOTE)
@@ -687,7 +687,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aFmtDQuote)
# Format > Single Quotes
self.aFmtSQuote = self.fmtMenu.addAction(self.tr("Wrap Single Quotes"))
self.aFmtSQuote = qtAddAction(self.fmtMenu, self.tr("Wrap Single Quotes"))
self.aFmtSQuote.setShortcut("Ctrl+'")
self.aFmtSQuote.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.S_QUOTE)
@@ -698,46 +698,46 @@ class GuiMainMenu(QMenuBar):
self.fmtMenu.addSeparator()
# Shortcodes
self.mShortcodes = self.fmtMenu.addMenu(self.tr("More Formats ..."))
self.mShortcodes = qtAddMenu(self.fmtMenu, self.tr("More Formats ..."))
# Shortcode Bold
self.aScBold = self.mShortcodes.addAction(self.tr("Bold (Shortcode)"))
self.aScBold = qtAddAction(self.mShortcodes, self.tr("Bold (Shortcode)"))
self.aScBold.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_BOLD)
)
# Shortcode Italic
self.aScItalic = self.mShortcodes.addAction(self.tr("Italics (Shortcode)"))
self.aScItalic = qtAddAction(self.mShortcodes, self.tr("Italics (Shortcode)"))
self.aScItalic.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_ITALIC)
)
# Shortcode Strikethrough
self.aScStrike = self.mShortcodes.addAction(self.tr("Strikethrough (Shortcode)"))
self.aScStrike = qtAddAction(self.mShortcodes, self.tr("Strikethrough (Shortcode)"))
self.aScStrike.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_STRIKE)
)
# Shortcode Underline
self.aScULine = self.mShortcodes.addAction(self.tr("Underline"))
self.aScULine = qtAddAction(self.mShortcodes, self.tr("Underline"))
self.aScULine.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_ULINE)
)
# Shortcode Mark
self.aScMark = self.mShortcodes.addAction(self.tr("Highlight"))
self.aScMark = qtAddAction(self.mShortcodes, self.tr("Highlight"))
self.aScMark.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_MARK)
)
# Shortcode Superscript
self.aScSuper = self.mShortcodes.addAction(self.tr("Superscript"))
self.aScSuper = qtAddAction(self.mShortcodes, self.tr("Superscript"))
self.aScSuper.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_SUP)
)
# Shortcode Subscript
self.aScSub = self.mShortcodes.addAction(self.tr("Subscript"))
self.aScSub = qtAddAction(self.mShortcodes, self.tr("Subscript"))
self.aScSub.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_SUB)
)
@@ -746,7 +746,7 @@ class GuiMainMenu(QMenuBar):
self.fmtMenu.addSeparator()
# Format > Heading 1 (Partition)
self.aFmtHead1 = self.fmtMenu.addAction(trConst(nwStyles.T_LABEL["H1"]))
self.aFmtHead1 = qtAddAction(self.fmtMenu, trConst(nwStyles.T_LABEL["H1"]))
self.aFmtHead1.setShortcut("Ctrl+1")
self.aFmtHead1.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H1)
@@ -754,7 +754,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aFmtHead1)
# Format > Heading 2 (Chapter)
self.aFmtHead2 = self.fmtMenu.addAction(trConst(nwStyles.T_LABEL["H2"]))
self.aFmtHead2 = qtAddAction(self.fmtMenu, trConst(nwStyles.T_LABEL["H2"]))
self.aFmtHead2.setShortcut("Ctrl+2")
self.aFmtHead2.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H2)
@@ -762,7 +762,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aFmtHead2)
# Format > Heading 3 (Scene)
self.aFmtHead3 = self.fmtMenu.addAction(trConst(nwStyles.T_LABEL["H3"]))
self.aFmtHead3 = qtAddAction(self.fmtMenu, trConst(nwStyles.T_LABEL["H3"]))
self.aFmtHead3.setShortcut("Ctrl+3")
self.aFmtHead3.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H3)
@@ -770,7 +770,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aFmtHead3)
# Format > Heading 4 (Section)
self.aFmtHead4 = self.fmtMenu.addAction(trConst(nwStyles.T_LABEL["H4"]))
self.aFmtHead4 = qtAddAction(self.fmtMenu, trConst(nwStyles.T_LABEL["H4"]))
self.aFmtHead4.setShortcut("Ctrl+4")
self.aFmtHead4.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H4)
@@ -781,19 +781,19 @@ class GuiMainMenu(QMenuBar):
self.fmtMenu.addSeparator()
# Format > Novel Title
self.aFmtTitle = self.fmtMenu.addAction(self.tr("Novel Title"))
self.aFmtTitle = qtAddAction(self.fmtMenu, self.tr("Novel Title"))
self.aFmtTitle.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_TTL)
)
# Format > Unnumbered Chapter
self.aFmtUnNum = self.fmtMenu.addAction(self.tr("Unnumbered Chapter"))
self.aFmtUnNum = qtAddAction(self.fmtMenu, self.tr("Unnumbered Chapter"))
self.aFmtUnNum.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_UNN)
)
# Format > Alternative Scene
self.aFmtHardSc = self.fmtMenu.addAction(self.tr("Alternative Scene"))
self.aFmtHardSc = qtAddAction(self.fmtMenu, self.tr("Alternative Scene"))
self.aFmtHardSc.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_HSC)
)
@@ -802,7 +802,7 @@ class GuiMainMenu(QMenuBar):
self.fmtMenu.addSeparator()
# Format > Align Left
self.aFmtAlignLeft = self.fmtMenu.addAction(self.tr("Align Left"))
self.aFmtAlignLeft = qtAddAction(self.fmtMenu, self.tr("Align Left"))
self.aFmtAlignLeft.setShortcut("Ctrl+5")
self.aFmtAlignLeft.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.ALIGN_L)
@@ -810,7 +810,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aFmtAlignLeft)
# Format > Align Centre
self.aFmtAlignCentre = self.fmtMenu.addAction(self.tr("Align Centre"))
self.aFmtAlignCentre = qtAddAction(self.fmtMenu, self.tr("Align Centre"))
self.aFmtAlignCentre.setShortcut("Ctrl+6")
self.aFmtAlignCentre.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.ALIGN_C)
@@ -818,7 +818,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aFmtAlignCentre)
# Format > Align Right
self.aFmtAlignRight = self.fmtMenu.addAction(self.tr("Align Right"))
self.aFmtAlignRight = qtAddAction(self.fmtMenu, self.tr("Align Right"))
self.aFmtAlignRight.setShortcut("Ctrl+7")
self.aFmtAlignRight.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.ALIGN_R)
@@ -829,7 +829,7 @@ class GuiMainMenu(QMenuBar):
self.fmtMenu.addSeparator()
# Format > Indent Left
self.aFmtIndentLeft = self.fmtMenu.addAction(self.tr("Indent Left"))
self.aFmtIndentLeft = qtAddAction(self.fmtMenu, self.tr("Indent Left"))
self.aFmtIndentLeft.setShortcut("Ctrl+8")
self.aFmtIndentLeft.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.INDENT_L)
@@ -837,7 +837,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aFmtIndentLeft)
# Format > Indent Right
self.aFmtIndentRight = self.fmtMenu.addAction(self.tr("Indent Right"))
self.aFmtIndentRight = qtAddAction(self.fmtMenu, self.tr("Indent Right"))
self.aFmtIndentRight.setShortcut("Ctrl+9")
self.aFmtIndentRight.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.INDENT_R)
@@ -848,7 +848,7 @@ class GuiMainMenu(QMenuBar):
self.fmtMenu.addSeparator()
# Format > Comment
self.aFmtComment = self.fmtMenu.addAction(self.tr("Toggle Comment"))
self.aFmtComment = qtAddAction(self.fmtMenu, self.tr("Toggle Comment"))
self.aFmtComment.setShortcut("Ctrl+/")
self.aFmtComment.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_COM)
@@ -856,14 +856,14 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aFmtComment)
# Format > Ignore Text
self.aFmtIgnore = self.fmtMenu.addAction(self.tr("Toggle Ignore Text"))
self.aFmtIgnore = qtAddAction(self.fmtMenu, self.tr("Toggle Ignore Text"))
self.aFmtIgnore.setShortcut("Ctrl+Shift+D")
self.aFmtIgnore.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_IGN)
)
# Format > Remove Block Format
self.aFmtNoFormat = self.fmtMenu.addAction(self.tr("Remove Block Format"))
self.aFmtNoFormat = qtAddAction(self.fmtMenu, self.tr("Remove Block Format"))
self.aFmtNoFormat.setShortcuts(["Ctrl+0", "Ctrl+Shift+/"])
self.aFmtNoFormat.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_TXT)
@@ -874,19 +874,19 @@ class GuiMainMenu(QMenuBar):
self.fmtMenu.addSeparator()
# Format > Replace Straight Single Quotes
self.aFmtReplSng = self.fmtMenu.addAction(self.tr("Replace Straight Single Quotes"))
self.aFmtReplSng = qtAddAction(self.fmtMenu, self.tr("Replace Straight Single Quotes"))
self.aFmtReplSng.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.REPL_SNG)
)
# Format > Replace Straight Double Quotes
self.aFmtReplDbl = self.fmtMenu.addAction(self.tr("Replace Straight Double Quotes"))
self.aFmtReplDbl = qtAddAction(self.fmtMenu, self.tr("Replace Straight Double Quotes"))
self.aFmtReplDbl.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.REPL_DBL)
)
# Format > Remove In-Paragraph Breaks
self.aFmtRmBreaks = self.fmtMenu.addAction(self.tr("Remove In-Paragraph Breaks"))
self.aFmtRmBreaks = qtAddAction(self.fmtMenu, self.tr("Remove In-Paragraph Breaks"))
self.aFmtRmBreaks.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.RM_BREAKS)
)
@@ -896,28 +896,28 @@ class GuiMainMenu(QMenuBar):
def _buildSearchMenu(self) -> None:
"""Assemble the Search menu."""
# Search
self.srcMenu = self.addMenu(self.tr("&Search"))
self.srcMenu = qtAddMenu(self, self.tr("&Search"))
# Search > Find
self.aFind = self.srcMenu.addAction(self.tr("Find"))
self.aFind = qtAddAction(self.srcMenu, self.tr("Find"))
self.aFind.setShortcut("Ctrl+F")
self.aFind.triggered.connect(qtLambda(self.mainGui.docEditor.beginSearch))
self.mainGui.addAction(self.aFind)
# Search > Replace
self.aReplace = self.srcMenu.addAction(self.tr("Replace"))
self.aReplace = qtAddAction(self.srcMenu, self.tr("Replace"))
self.aReplace.setShortcut("Ctrl+=" if CONFIG.osDarwin else "Ctrl+H")
self.aReplace.triggered.connect(qtLambda(self.mainGui.docEditor.beginReplace))
self.mainGui.addAction(self.aReplace)
# Search > Find Next
self.aFindNext = self.srcMenu.addAction(self.tr("Find Next"))
self.aFindNext = qtAddAction(self.srcMenu, self.tr("Find Next"))
self.aFindNext.setShortcuts(["Ctrl+G", "F3"] if CONFIG.osDarwin else ["F3", "Ctrl+G"])
self.aFindNext.triggered.connect(qtLambda(self.mainGui.docEditor.findNext))
self.mainGui.addAction(self.aFindNext)
# Search > Find Prev
self.aFindPrev = self.srcMenu.addAction(self.tr("Find Previous"))
self.aFindPrev = qtAddAction(self.srcMenu, self.tr("Find Previous"))
self.aFindPrev.setShortcuts(
["Ctrl+Shift+G", "Shift+F3"] if CONFIG.osDarwin else ["Shift+F3", "Ctrl+Shift+G"]
)
@@ -925,7 +925,7 @@ class GuiMainMenu(QMenuBar):
self.mainGui.addAction(self.aFindPrev)
# Search > Replace Next
self.aReplaceNext = self.srcMenu.addAction(self.tr("Replace Next"))
self.aReplaceNext = qtAddAction(self.srcMenu, self.tr("Replace Next"))
self.aReplaceNext.setShortcut("Ctrl+Shift+1")
self.aReplaceNext.triggered.connect(qtLambda(self.mainGui.docEditor.replaceNext))
self.mainGui.addAction(self.aReplaceNext)
@@ -934,7 +934,7 @@ class GuiMainMenu(QMenuBar):
self.srcMenu.addSeparator()
# Search > Find in Project
self.aFindProj = self.srcMenu.addAction(self.tr("Find in Project"))
self.aFindProj = qtAddAction(self.srcMenu, self.tr("Find in Project"))
self.aFindProj.setShortcut("Ctrl+Shift+F")
self.aFindProj.triggered.connect(lambda: self.requestViewChange.emit(nwView.SEARCH))
@@ -943,17 +943,17 @@ class GuiMainMenu(QMenuBar):
def _buildToolsMenu(self) -> None:
"""Assemble the Tools menu."""
# Tools
self.toolsMenu = self.addMenu(self.tr("&Tools"))
self.toolsMenu = qtAddMenu(self, self.tr("&Tools"))
# Tools > Check Spelling
self.aSpellCheck = self.toolsMenu.addAction(self.tr("Check Spelling"))
self.aSpellCheck = qtAddAction(self.toolsMenu, self.tr("Check Spelling"))
self.aSpellCheck.setCheckable(True)
self.aSpellCheck.setChecked(SHARED.project.data.spellCheck)
self.aSpellCheck.triggered.connect(self._toggleSpellCheck) # triggered, not toggled!
self.aSpellCheck.setShortcut("Ctrl+F7")
self.mainGui.addAction(self.aSpellCheck)
self.mSelectLanguage = self.toolsMenu.addMenu(self.tr("Spell Check Language"))
self.mSelectLanguage = qtAddMenu(self.toolsMenu, self.tr("Spell Check Language"))
languages = SHARED.spelling.listDictionaries()
languages.insert(0, ("None", self.tr("Default")))
for n, (tag, language) in enumerate(languages):
@@ -963,25 +963,25 @@ class GuiMainMenu(QMenuBar):
self.mSelectLanguage.addAction(aSpell)
# Tools > Re-Run Spell Check
self.aReRunSpell = self.toolsMenu.addAction(self.tr("Re-Run Spell Check"))
self.aReRunSpell = qtAddAction(self.toolsMenu, self.tr("Re-Run Spell Check"))
self.aReRunSpell.setShortcut("F7")
self.aReRunSpell.triggered.connect(qtLambda(self.mainGui.docEditor.spellCheckDocument))
self.mainGui.addAction(self.aReRunSpell)
# Tools > Project Word List
self.aEditWordList = self.toolsMenu.addAction(self.tr("Project Word List"))
self.aEditWordList = qtAddAction(self.toolsMenu, self.tr("Project Word List"))
self.aEditWordList.triggered.connect(self.mainGui.showProjectWordListDialog)
# Tools > Add Dictionaries
if CONFIG.osWindows or CONFIG.isDebug:
self.aAddDicts = self.toolsMenu.addAction(self.tr("Add Dictionaries"))
self.aAddDicts = qtAddAction(self.toolsMenu, self.tr("Add Dictionaries"))
self.aAddDicts.triggered.connect(self.mainGui.showDictionariesDialog)
# Tools > Separator
self.toolsMenu.addSeparator()
# Tools > Rebuild Index
self.aRebuildIndex = self.toolsMenu.addAction(self.tr("Rebuild Index"))
self.aRebuildIndex = qtAddAction(self.toolsMenu, self.tr("Rebuild Index"))
self.aRebuildIndex.setShortcut("F9")
self.aRebuildIndex.triggered.connect(qtLambda(self.mainGui.rebuildIndex))
@@ -989,21 +989,21 @@ class GuiMainMenu(QMenuBar):
self.toolsMenu.addSeparator()
# Tools > Backup Project
self.aBackupProject = self.toolsMenu.addAction(self.tr("Backup Project"))
self.aBackupProject = qtAddAction(self.toolsMenu, self.tr("Backup Project"))
self.aBackupProject.triggered.connect(qtLambda(SHARED.project.backupProject, True))
# Tools > Build Manuscript
self.aBuildManuscript = self.toolsMenu.addAction(self.tr("Build Manuscript"))
self.aBuildManuscript = qtAddAction(self.toolsMenu, self.tr("Build Manuscript"))
self.aBuildManuscript.setShortcut("F5")
self.aBuildManuscript.triggered.connect(self.mainGui.showBuildManuscriptDialog)
# Tools > Writing Statistics
self.aWritingStats = self.toolsMenu.addAction(self.tr("Writing Statistics"))
self.aWritingStats = qtAddAction(self.toolsMenu, self.tr("Writing Statistics"))
self.aWritingStats.setShortcut("F6")
self.aWritingStats.triggered.connect(self.mainGui.showWritingStatsDialog)
# Tools > Preferences
self.aPreferences = self.toolsMenu.addAction(self.tr("Preferences"))
self.aPreferences = qtAddAction(self.toolsMenu, self.tr("Preferences"))
self.aPreferences.setShortcut("Ctrl+,")
self.aPreferences.setMenuRole(QAction.MenuRole.PreferencesRole)
self.aPreferences.triggered.connect(self.mainGui.showPreferencesDialog)
@@ -1014,15 +1014,15 @@ class GuiMainMenu(QMenuBar):
def _buildHelpMenu(self) -> None:
"""Assemble the Help menu."""
# Help
self.helpMenu = self.addMenu(self.tr("&Help"))
self.helpMenu = qtAddMenu(self, self.tr("&Help"))
# Help > About
self.aAboutNW = self.helpMenu.addAction(self.tr("About novelWriter"))
self.aAboutNW = qtAddAction(self.helpMenu, self.tr("About novelWriter"))
self.aAboutNW.setMenuRole(QAction.MenuRole.AboutRole)
self.aAboutNW.triggered.connect(self.mainGui.showAboutNWDialog)
# Help > About Qt
self.aAboutQt = self.helpMenu.addAction(self.tr("About Qt"))
self.aAboutQt = qtAddAction(self.helpMenu, self.tr("About Qt"))
self.aAboutQt.setMenuRole(QAction.MenuRole.AboutQtRole)
self.aAboutQt.triggered.connect(self.mainGui.showAboutQtDialog)
@@ -1030,14 +1030,14 @@ class GuiMainMenu(QMenuBar):
self.helpMenu.addSeparator()
# Help > User Manual (Online)
self.aHelpDocs = self.helpMenu.addAction(self.tr("User Manual (Online)"))
self.aHelpDocs = qtAddAction(self.helpMenu, self.tr("User Manual (Online)"))
self.aHelpDocs.setShortcut("F1")
self.aHelpDocs.triggered.connect(qtLambda(SHARED.openWebsite, nwConst.URL_DOCS))
self.mainGui.addAction(self.aHelpDocs)
# Help > User Manual (PDF)
if isinstance(CONFIG.pdfDocs, Path):
self.aPdfDocs = self.helpMenu.addAction(self.tr("User Manual (PDF)"))
self.aPdfDocs = qtAddAction(self.helpMenu, self.tr("User Manual (PDF)"))
self.aPdfDocs.setShortcut("Shift+F1")
self.aPdfDocs.triggered.connect(self._openUserManualFile)
self.mainGui.addAction(self.aPdfDocs)
@@ -1046,15 +1046,15 @@ class GuiMainMenu(QMenuBar):
self.helpMenu.addSeparator()
# Document > Report an Issue
self.aIssue = self.helpMenu.addAction(self.tr("Report an Issue (GitHub)"))
self.aIssue = qtAddAction(self.helpMenu, self.tr("Report an Issue (GitHub)"))
self.aIssue.triggered.connect(qtLambda(SHARED.openWebsite, nwConst.URL_REPORT))
# Document > Ask a Question
self.aQuestion = self.helpMenu.addAction(self.tr("Ask a Question (GitHub)"))
self.aQuestion = qtAddAction(self.helpMenu, self.tr("Ask a Question (GitHub)"))
self.aQuestion.triggered.connect(qtLambda(SHARED.openWebsite, nwConst.URL_HELP))
# Document > Main Website
self.aWebsite = self.helpMenu.addAction(self.tr("The novelWriter Website"))
self.aWebsite = qtAddAction(self.helpMenu, self.tr("The novelWriter Website"))
self.aWebsite.triggered.connect(qtLambda(SHARED.openWebsite, nwConst.URL_WEB))
return
+18 -18
View File
@@ -38,7 +38,7 @@ from PyQt6.QtWidgets import (
)
from novelwriter import CONFIG, SHARED
from novelwriter.common import minmax, qtLambda
from novelwriter.common import minmax, qtAddAction, qtAddMenu, qtLambda
from novelwriter.constants import nwKeyWords, nwLabels, nwStyles, trConst
from novelwriter.core.index import IndexHeading
from novelwriter.enum import nwChange, nwDocMode, nwItemClass, nwOutline
@@ -199,7 +199,6 @@ class GuiNovelToolBar(QWidget):
self.novelView = novelView
iSz = SHARED.theme.baseIconSize
mPx = CONFIG.pxInt(2)
self.setContentsMargins(0, 0, 0, 0)
self.setAutoFillBackground(True)
@@ -211,7 +210,7 @@ class GuiNovelToolBar(QWidget):
self.novelValue = NovelSelector(self)
self.novelValue.setFont(selFont)
self.novelValue.setListFormat(self.tr("Outline of {0}"))
self.novelValue.setMinimumWidth(CONFIG.pxInt(150))
self.novelValue.setMinimumWidth(150)
self.novelValue.setSizePolicy(QtSizeExpanding, QtSizeExpanding)
self.novelValue.novelSelectionChanged.connect(self.setCurrentRoot)
@@ -227,7 +226,7 @@ class GuiNovelToolBar(QWidget):
# More Options Menu
self.mMore = QMenu(self)
self.mLastCol = self.mMore.addMenu(self.tr("Last Column"))
self.mLastCol = qtAddMenu(self.mMore, self.tr("Last Column"))
self.gLastCol = QActionGroup(self.mMore)
self.aLastCol = {}
self._addLastColAction(NovelTreeColumn.HIDDEN, self.tr("Hidden"))
@@ -236,7 +235,7 @@ class GuiNovelToolBar(QWidget):
self._addLastColAction(NovelTreeColumn.PLOT, self.tr("Novel Plot"))
self.mLastCol.addSeparator()
self.aLastColSize = self.mLastCol.addAction(self.tr("Column Size"))
self.aLastColSize = qtAddAction(self.mLastCol, self.tr("Column Size"))
self.aLastColSize.triggered.connect(self._selectLastColumnSize)
self.tbMore = NIconToolButton(self, iSz)
@@ -249,7 +248,7 @@ class GuiNovelToolBar(QWidget):
self.outerBox.addWidget(self.tbNovel)
self.outerBox.addWidget(self.tbRefresh)
self.outerBox.addWidget(self.tbMore)
self.outerBox.setContentsMargins(mPx, mPx, 0, mPx)
self.outerBox.setContentsMargins(2, 2, 0, 2)
self.outerBox.setSpacing(0)
self.setLayout(self.outerBox)
@@ -343,7 +342,7 @@ class GuiNovelToolBar(QWidget):
def _addLastColAction(self, colType: NovelTreeColumn, actionLabel: str) -> None:
"""Add a column selection entry to the last column menu."""
aLast = self.mLastCol.addAction(actionLabel)
aLast = qtAddAction(self.mLastCol, actionLabel)
aLast.setCheckable(True)
aLast.setActionGroup(self.gLastCol)
aLast.triggered.connect(qtLambda(self.setLastColType, colType))
@@ -388,7 +387,6 @@ class GuiNovelTree(QTreeWidget):
iPx = SHARED.theme.baseIconHeight
iSz = SHARED.theme.baseIconSize
cMg = CONFIG.pxInt(6)
self.setIconSize(iSz)
self.setFrameStyle(QFrame.Shape.NoFrame)
@@ -403,13 +401,13 @@ class GuiNovelTree(QTreeWidget):
self.setDragEnabled(False)
# Lock the column sizes
treeHeader = self.header()
treeHeader.setStretchLastSection(False)
treeHeader.setMinimumSectionSize(iPx + cMg)
treeHeader.setSectionResizeMode(self.C_TITLE, QtHeaderStretch)
treeHeader.setSectionResizeMode(self.C_WORDS, QtHeaderToContents)
treeHeader.setSectionResizeMode(self.C_EXTRA, QtHeaderToContents)
treeHeader.setSectionResizeMode(self.C_MORE, QtHeaderToContents)
if header := self.header():
header.setStretchLastSection(False)
header.setMinimumSectionSize(iPx + 6)
header.setSectionResizeMode(self.C_TITLE, QtHeaderStretch)
header.setSectionResizeMode(self.C_WORDS, QtHeaderToContents)
header.setSectionResizeMode(self.C_EXTRA, QtHeaderToContents)
header.setSectionResizeMode(self.C_MORE, QtHeaderToContents)
# Pre-Generate Tree Formatting
fH1 = self.font()
@@ -678,8 +676,9 @@ class GuiNovelTree(QTreeWidget):
return
def _updateTreeItemValues(self, trItem: QTreeWidgetItem, idxItem: IndexHeading,
tHandle: str, sTitle: str) -> None:
def _updateTreeItemValues(
self, trItem: QTreeWidgetItem, idxItem: IndexHeading, tHandle: str, sTitle: str
) -> None:
"""Set the tree item values from the index entry."""
iLevel = nwStyles.H_LEVEL.get(idxItem.level, 0)
hDec = SHARED.theme.getHeaderDecoration(iLevel)
@@ -691,7 +690,8 @@ class GuiNovelTree(QTreeWidget):
trItem.setData(self.C_MORE, QtDecoration, self._pMore)
# Custom column
mW = int(self._lastColSize * self.viewport().width())
viewport = self.viewport()
mW = int(self._lastColSize * (viewport.width() if viewport else 100))
lastText, toolTip = self._getLastColumnText(tHandle, sTitle)
elideText = self.fontMetrics().elidedText(lastText, Qt.TextElideMode.ElideRight, mW)
trItem.setText(self.C_EXTRA, elideText)
+30 -39
View File
@@ -78,7 +78,7 @@ class GuiOutlineView(QWidget):
# Assemble
self.outerBox = QVBoxLayout()
self.outerBox.setContentsMargins(0, 0, CONFIG.pxInt(4), 0)
self.outerBox.setContentsMargins(0, 0, 4, 0)
self.outerBox.addWidget(self.outlineBar)
self.outerBox.addWidget(self.splitOutline)
@@ -225,11 +225,11 @@ class GuiOutlineToolBar(QToolBar):
self.novelLabel = NColourLabel(
self.tr("Outline of"), self, scale=NColourLabel.HEADER_SCALE, bold=True
)
self.novelLabel.setContentsMargins(0, 0, CONFIG.pxInt(12), 0)
self.novelLabel.setContentsMargins(0, 0, 12, 0)
self.novelValue = NovelSelector(self)
self.novelValue.setIncludeAll(True)
self.novelValue.setMinimumWidth(CONFIG.pxInt(200))
self.novelValue.setMinimumWidth(200)
self.novelValue.novelSelectionChanged.connect(self._novelValueChanged)
# Actions
@@ -390,8 +390,8 @@ class GuiOutlineTree(QTreeWidget):
self.setIconSize(SHARED.theme.baseIconSize)
self.setIndentation(0)
self.treeHead = self.header()
self.treeHead.sectionMoved.connect(self._columnMoved)
if header := self.header():
header.sectionMoved.connect(self._columnMoved)
# Pre-Generate Tree Formatting
fH1 = self.font()
@@ -623,7 +623,7 @@ class GuiOutlineTree(QTreeWidget):
continue
tmpOrder.append(nwOutline[name])
tmpHidden[nwOutline[name]] = hidden
tmpWidth[nwOutline[name]] = CONFIG.pxInt(width)
tmpWidth[nwOutline[name]] = width
except Exception:
logger.error("Invalid column state")
logException()
@@ -647,26 +647,22 @@ class GuiOutlineTree(QTreeWidget):
save the current width of hidden columns though. This preserves
the last known width in case they're unhidden again.
"""
# If we haven't built the tree, there is nothing to save.
if self._lastBuild == 0:
return
colState = {}
for iCol in range(self.columnCount()):
hItem = self._treeOrder[iCol]
iLog = self.treeHead.logicalIndex(iCol)
logHidden = self.isColumnHidden(iLog)
orgWidth = CONFIG.rpxInt(self._colWidth[hItem])
logWidth = CONFIG.rpxInt(self.columnWidth(iLog))
colState[hItem.name] = [
logHidden, orgWidth if logHidden and logWidth == 0 else logWidth
]
logger.debug("Saving State: GuiOutline")
pOptions = SHARED.project.options
pOptions.setValue("GuiOutline", "columnState", colState)
pOptions.saveSettings()
if self._lastBuild > 0 and (header := self.header()):
colState = {}
for iCol in range(self.columnCount()):
hItem = self._treeOrder[iCol]
iLog = header.logicalIndex(iCol)
logHidden = self.isColumnHidden(iLog)
orgWidth = self._colWidth[hItem]
logWidth = self.columnWidth(iLog)
colState[hItem.name] = [
logHidden, orgWidth if logHidden and logWidth == 0 else logWidth
]
logger.debug("Saving State: GuiOutline")
pOptions = SHARED.project.options
pOptions.setValue("GuiOutline", "columnState", colState)
pOptions.saveSettings()
return
def _populateTree(self, rootHandle: str | None) -> None:
@@ -819,8 +815,6 @@ class GuiOutlineDetails(QScrollArea):
minTitle = 30*SHARED.theme.textNWidth
maxTitle = 40*SHARED.theme.textNWidth
wCount = SHARED.theme.getTextWidth("999,999")
hSpace = int(CONFIG.pxInt(10))
vSpace = int(CONFIG.pxInt(4))
bFont = SHARED.theme.guiFontB
@@ -899,8 +893,8 @@ class GuiOutlineDetails(QScrollArea):
self.mainForm.setColumnStretch(1, 1)
self.mainForm.setRowStretch(4, 1)
self.mainForm.setHorizontalSpacing(hSpace)
self.mainForm.setVerticalSpacing(vSpace)
self.mainForm.setHorizontalSpacing(10)
self.mainForm.setVerticalSpacing(4)
# Selected Item Tags
self.tagsForm = QGridLayout()
@@ -923,8 +917,8 @@ class GuiOutlineDetails(QScrollArea):
self.tagsForm.setColumnStretch(1, 1)
self.tagsForm.setRowStretch(len(self.tagValues), 1)
self.tagsForm.setHorizontalSpacing(hSpace)
self.tagsForm.setVerticalSpacing(vSpace)
self.tagsForm.setHorizontalSpacing(10)
self.tagsForm.setVerticalSpacing(4)
# Assemble
self.mainSplit = QSplitter(Qt.Orientation.Horizontal)
@@ -965,21 +959,18 @@ class GuiOutlineDetails(QScrollArea):
width = parent.width() if isinstance(parent, QWidget) else 1000
pOptions = SHARED.project.options
self.mainSplit.setSizes([
CONFIG.pxInt(pOptions.getInt("GuiOutlineDetails", "detailsWidth", width//3)),
CONFIG.pxInt(pOptions.getInt("GuiOutlineDetails", "tagsWidth", 2*width//3))
pOptions.getInt("GuiOutlineDetails", "detailsWidth", width//3),
pOptions.getInt("GuiOutlineDetails", "tagsWidth", 2*width//3),
])
return
def saveGuiSettings(self) -> None:
"""Run close project tasks."""
mainSplit = self.mainSplit.sizes()
detailsWidth = CONFIG.rpxInt(mainSplit[0])
tagsWidth = CONFIG.rpxInt(mainSplit[1])
logger.debug("Saving State: GuiOutlineDetails")
mainSplit = self.mainSplit.sizes()
pOptions = SHARED.project.options
pOptions.setValue("GuiOutlineDetails", "detailsWidth", detailsWidth)
pOptions.setValue("GuiOutlineDetails", "tagsWidth", tagsWidth)
pOptions.setValue("GuiOutlineDetails", "detailsWidth", mainSplit[0])
pOptions.setValue("GuiOutlineDetails", "tagsWidth", mainSplit[1])
return
def clearDetails(self) -> None:
+60 -56
View File
@@ -40,7 +40,7 @@ from PyQt6.QtWidgets import (
)
from novelwriter import CONFIG, SHARED
from novelwriter.common import qtLambda
from novelwriter.common import qtAddAction, qtAddMenu, qtLambda
from novelwriter.constants import nwLabels, nwStyles, nwUnicode, trConst
from novelwriter.core.coretools import DocDuplicator, DocMerger, DocSplitter
from novelwriter.core.item import NWItem
@@ -243,7 +243,6 @@ class GuiProjectToolBar(QWidget):
self.projTree = projView.projTree
iSz = SHARED.theme.baseIconSize
mPx = CONFIG.pxInt(2)
self.setContentsMargins(0, 0, 0, 0)
self.setAutoFillBackground(True)
@@ -274,27 +273,27 @@ class GuiProjectToolBar(QWidget):
# Add Item Menu
self.mAdd = QMenu(self)
self.aAddEmpty = self.mAdd.addAction(trConst(nwLabels.ITEM_DESCRIPTION["document"]))
self.aAddEmpty = qtAddAction(self.mAdd, trConst(nwLabels.ITEM_DESCRIPTION["document"]))
self.aAddEmpty.triggered.connect(
qtLambda(self.projTree.newTreeItem, nwItemType.FILE, hLevel=0, isNote=False)
)
self.aAddChap = self.mAdd.addAction(trConst(nwLabels.ITEM_DESCRIPTION["doc_h2"]))
self.aAddChap = qtAddAction(self.mAdd, trConst(nwLabels.ITEM_DESCRIPTION["doc_h2"]))
self.aAddChap.triggered.connect(
qtLambda(self.projTree.newTreeItem, nwItemType.FILE, hLevel=2, isNote=False)
)
self.aAddScene = self.mAdd.addAction(trConst(nwLabels.ITEM_DESCRIPTION["doc_h3"]))
self.aAddScene = qtAddAction(self.mAdd, trConst(nwLabels.ITEM_DESCRIPTION["doc_h3"]))
self.aAddScene.triggered.connect(
qtLambda(self.projTree.newTreeItem, nwItemType.FILE, hLevel=3, isNote=False)
)
self.aAddNote = self.mAdd.addAction(trConst(nwLabels.ITEM_DESCRIPTION["note"]))
self.aAddNote = qtAddAction(self.mAdd, trConst(nwLabels.ITEM_DESCRIPTION["note"]))
self.aAddNote.triggered.connect(
qtLambda(self.projTree.newTreeItem, nwItemType.FILE, hLevel=1, isNote=True)
)
self.aAddFolder = self.mAdd.addAction(trConst(nwLabels.ITEM_DESCRIPTION["folder"]))
self.aAddFolder = qtAddAction(self.mAdd, trConst(nwLabels.ITEM_DESCRIPTION["folder"]))
self.aAddFolder.triggered.connect(
qtLambda(self.projTree.newTreeItem, nwItemType.FOLDER)
)
@@ -304,7 +303,7 @@ class GuiProjectToolBar(QWidget):
self.mTemplates.menuItemTriggered.connect(lambda h: self.newDocumentFromTemplate.emit(h))
self.mAdd.addMenu(self.mTemplates)
self.mAddRoot = self.mAdd.addMenu(trConst(nwLabels.ITEM_DESCRIPTION["root"]))
self.mAddRoot = qtAddMenu(self.mAdd, trConst(nwLabels.ITEM_DESCRIPTION["root"]))
self._buildRootMenu()
self.tbAdd = NIconToolButton(self, iSz)
@@ -315,13 +314,13 @@ class GuiProjectToolBar(QWidget):
# More Options Menu
self.mMore = QMenu(self)
self.aExpand = self.mMore.addAction(self.tr("Expand All"))
self.aExpand = qtAddAction(self.mMore, self.tr("Expand All"))
self.aExpand.triggered.connect(self.projTree.expandAll)
self.aCollapse = self.mMore.addAction(self.tr("Collapse All"))
self.aCollapse = qtAddAction(self.mMore, self.tr("Collapse All"))
self.aCollapse.triggered.connect(self.projTree.collapseAll)
self.aEmptyTrash = self.mMore.addAction(self.tr("Empty Trash"))
self.aEmptyTrash = qtAddAction(self.mMore, self.tr("Empty Trash"))
self.aEmptyTrash.triggered.connect(self.projTree.emptyTrash)
self.tbMore = NIconToolButton(self, iSz)
@@ -336,7 +335,7 @@ class GuiProjectToolBar(QWidget):
self.outerBox.addWidget(self.tbMoveD)
self.outerBox.addWidget(self.tbAdd)
self.outerBox.addWidget(self.tbMore)
self.outerBox.setContentsMargins(mPx, mPx, 0, mPx)
self.outerBox.setContentsMargins(2, 2, 0, 2)
self.outerBox.setSpacing(0)
self.setLayout(self.outerBox)
@@ -392,7 +391,7 @@ class GuiProjectToolBar(QWidget):
logger.debug("Rebuilding quick links menu")
self.mQuick.clear()
for tHandle, nwItem in SHARED.project.tree.iterRoots(None):
action = self.mQuick.addAction(nwItem.itemName)
action = qtAddAction(self.mQuick, nwItem.itemName)
action.setData(tHandle)
action.setIcon(SHARED.theme.getIcon(nwLabels.CLASS_ICON[nwItem.itemClass], "root"))
action.triggered.connect(
@@ -440,7 +439,7 @@ class GuiProjectToolBar(QWidget):
def _buildRootMenu(self) -> None:
"""Build the rood folder menu."""
def addClass(itemClass: nwItemClass) -> None:
aNew = self.mAddRoot.addAction(trConst(nwLabels.CLASS_NAME[itemClass]))
aNew = qtAddAction(self.mAddRoot, trConst(nwLabels.CLASS_NAME[itemClass]))
aNew.setIcon(SHARED.theme.getIcon(nwLabels.CLASS_ICON[itemClass], "root"))
aNew.triggered.connect(
qtLambda(self.projTree.newTreeItem, nwItemType.ROOT, itemClass)
@@ -561,17 +560,16 @@ class GuiProjectTree(QTreeView):
# Lock the column sizes
iPx = SHARED.theme.baseIconHeight
cMg = CONFIG.pxInt(6)
treeHeader = self.header()
treeHeader.setStretchLastSection(False)
treeHeader.setMinimumSectionSize(iPx + cMg)
treeHeader.setSectionResizeMode(ProjectNode.C_NAME, QtHeaderStretch)
treeHeader.setSectionResizeMode(ProjectNode.C_COUNT, QtHeaderToContents)
treeHeader.setSectionResizeMode(ProjectNode.C_ACTIVE, QtHeaderFixed)
treeHeader.setSectionResizeMode(ProjectNode.C_STATUS, QtHeaderFixed)
treeHeader.resizeSection(ProjectNode.C_ACTIVE, iPx + cMg)
treeHeader.resizeSection(ProjectNode.C_STATUS, iPx + cMg)
if header := self.header():
header.setStretchLastSection(False)
header.setMinimumSectionSize(iPx + 6)
header.setSectionResizeMode(ProjectNode.C_NAME, QtHeaderStretch)
header.setSectionResizeMode(ProjectNode.C_COUNT, QtHeaderToContents)
header.setSectionResizeMode(ProjectNode.C_ACTIVE, QtHeaderFixed)
header.setSectionResizeMode(ProjectNode.C_STATUS, QtHeaderFixed)
header.resizeSection(ProjectNode.C_ACTIVE, iPx + 6)
header.resizeSection(ProjectNode.C_STATUS, iPx + 6)
self.restoreExpandedState()
@@ -969,8 +967,9 @@ class GuiProjectTree(QTreeView):
else:
ctxMenu.buildSingleSelectMenu()
ctxMenu.exec(self.viewport().mapToGlobal(point))
ctxMenu.deleteLater()
if viewport := self.viewport():
ctxMenu.exec(viewport.mapToGlobal(point))
ctxMenu.deleteLater()
return
@@ -1091,7 +1090,8 @@ class _UpdatableMenu(QMenu):
def setActionsVisible(self, value: bool) -> None:
"""Set the visibility of root action."""
self.menuAction().setVisible(value)
if action := self.menuAction():
action.setVisible(value)
return
##
@@ -1135,7 +1135,7 @@ class _TreeContextMenu(QMenu):
def buildTrashMenu(self) -> None:
"""Build the special menu for the Trash folder."""
action = self.addAction(self.tr("Empty Trash"))
action = qtAddAction(self, self.tr("Empty Trash"))
action.triggered.connect(self._tree.emptyTrash)
if self._children:
self._expandCollapse()
@@ -1156,7 +1156,7 @@ class _TreeContextMenu(QMenu):
self.addSeparator()
# Edit Item Settings
action = self.addAction(self.tr("Rename"))
action = qtAddAction(self, self.tr("Rename"))
action.triggered.connect(qtLambda(self._view.renameTreeItem, self._handle))
if isFile:
self._itemHeader()
@@ -1171,7 +1171,7 @@ class _TreeContextMenu(QMenu):
# Process Item
if self._children:
self._expandCollapse()
action = self.addAction(self.tr("Duplicate"))
action = qtAddAction(self, self.tr("Duplicate"))
action.triggered.connect(qtLambda(self._tree.duplicateFromHandle, self._handle))
self._deleteOrTrash()
@@ -1191,12 +1191,12 @@ class _TreeContextMenu(QMenu):
def _docActions(self) -> None:
"""Add document actions."""
action = self.addAction(self.tr("Open Document"))
action = qtAddAction(self, self.tr("Open Document"))
action.triggered.connect(qtLambda(
self._view.openDocumentRequest.emit,
self._handle, nwDocMode.EDIT, "", True
))
action = self.addAction(self.tr("View Document"))
action = qtAddAction(self, self.tr("View Document"))
action.triggered.connect(qtLambda(
self._view.openDocumentRequest.emit,
self._handle, nwDocMode.VIEW, "", False
@@ -1205,7 +1205,7 @@ class _TreeContextMenu(QMenu):
def _itemCreation(self) -> None:
"""Add create item actions."""
menu = self.addMenu(self.tr("Create New ..."))
menu = qtAddMenu(self, self.tr("Create New ..."))
menu.addAction(self._view.projBar.aAddEmpty)
menu.addAction(self._view.projBar.aAddChap)
menu.addAction(self._view.projBar.aAddScene)
@@ -1217,7 +1217,7 @@ class _TreeContextMenu(QMenu):
"""Check if there is a header that can be used for rename."""
SHARED.saveEditor()
if hItem := SHARED.project.index.getItemHeading(self._handle, "T0001"):
action = self.addAction(self.tr("Rename to Heading"))
action = qtAddAction(self, self.tr("Rename to Heading"))
action.triggered.connect(
qtLambda(self._view.renameTreeItem, self._handle, hItem.title)
)
@@ -1226,50 +1226,54 @@ class _TreeContextMenu(QMenu):
def _itemActive(self) -> None:
"""Add Active/Inactive actions."""
if len(self._indices) > 1:
mSub = self.addMenu(self.tr("Set Active to ..."))
aOne = mSub.addAction(SHARED.theme.getIcon("checked"), self._tree.trActive)
mSub = qtAddMenu(self, self.tr("Set Active to ..."))
aOne = qtAddAction(mSub, self._tree.trActive)
aOne.setIcon(SHARED.theme.getIcon("checked"))
aOne.triggered.connect(qtLambda(self._iterItemActive, True))
aTwo = mSub.addAction(SHARED.theme.getIcon("unchecked"), self._tree.trInactive)
aTwo = qtAddAction(mSub, self._tree.trInactive)
aTwo.setIcon(SHARED.theme.getIcon("unchecked"))
aTwo.triggered.connect(qtLambda(self._iterItemActive, False))
else:
action = self.addAction(self.tr("Toggle Active"))
action = qtAddAction(self, self.tr("Toggle Active"))
action.triggered.connect(self._toggleItemActive)
return
def _itemStatusImport(self, multi: bool) -> None:
"""Add actions for changing status or importance."""
if self._item.isNovelLike():
menu = self.addMenu(self.tr("Set Status to ..."))
menu = qtAddMenu(self, self.tr("Set Status to ..."))
current = self._item.itemStatus
for key, entry in SHARED.project.data.itemStatus.iterItems():
name = entry.name
if not multi and current == key:
name += f" ({nwUnicode.U_CHECK})"
action = menu.addAction(entry.icon, name)
action = qtAddAction(menu, name)
action.setIcon(entry.icon)
if multi:
action.triggered.connect(qtLambda(self._iterSetItemStatus, key))
else:
action.triggered.connect(qtLambda(self._changeItemStatus, key))
menu.addSeparator()
action = menu.addAction(self.tr("Manage Labels ..."))
action = qtAddAction(menu, self.tr("Manage Labels ..."))
action.triggered.connect(qtLambda(
self._view.projectSettingsRequest.emit,
GuiProjectSettings.PAGE_STATUS
))
else:
menu = self.addMenu(self.tr("Set Importance to ..."))
menu = qtAddMenu(self, self.tr("Set Importance to ..."))
current = self._item.itemImport
for key, entry in SHARED.project.data.itemImport.iterItems():
name = entry.name
if not multi and current == key:
name += f" ({nwUnicode.U_CHECK})"
action = menu.addAction(entry.icon, name)
action = qtAddAction(menu, name)
action.setIcon(entry.icon)
if multi:
action.triggered.connect(qtLambda(self._iterSetItemImport, key))
else:
action.triggered.connect(qtLambda(self._changeItemImport, key))
menu.addSeparator()
action = menu.addAction(self.tr("Manage Labels ..."))
action = qtAddAction(menu, self.tr("Manage Labels ..."))
action.triggered.connect(qtLambda(
self._view.projectSettingsRequest.emit,
GuiProjectSettings.PAGE_IMPORT
@@ -1278,7 +1282,7 @@ class _TreeContextMenu(QMenu):
def _itemTransform(self, isFile: bool, isFolder: bool) -> None:
"""Add actions for the Transform menu."""
menu = self.addMenu(self.tr("Transform ..."))
menu = qtAddMenu(self, self.tr("Transform ..."))
trDoc = trConst(nwLabels.LAYOUT_NAME[nwItemLayout.DOCUMENT])
trNote = trConst(nwLabels.LAYOUT_NAME[nwItemLayout.NOTE])
@@ -1288,42 +1292,42 @@ class _TreeContextMenu(QMenu):
isNoteFile = isFile and self._item.isNoteLayout()
if isNoteFile and self._item.documentAllowed():
action = menu.addAction(self.tr("Convert to {0}").format(trDoc))
action = qtAddAction(menu, self.tr("Convert to {0}").format(trDoc))
action.triggered.connect(qtLambda(self._changeItemLayout, loDoc))
if isDocFile:
action = menu.addAction(self.tr("Convert to {0}").format(trNote))
action = qtAddAction(menu, self.tr("Convert to {0}").format(trNote))
action.triggered.connect(qtLambda(self._changeItemLayout, loNote))
if isFolder and self._item.documentAllowed():
action = menu.addAction(self.tr("Convert to {0}").format(trDoc))
action = qtAddAction(menu, self.tr("Convert to {0}").format(trDoc))
action.triggered.connect(qtLambda(self._convertFolderToFile, loDoc))
if isFolder:
action = menu.addAction(self.tr("Convert to {0}").format(trNote))
action = qtAddAction(menu, self.tr("Convert to {0}").format(trNote))
action.triggered.connect(qtLambda(self._convertFolderToFile, loNote))
if self._children and isFile:
action = menu.addAction(self.tr("Merge Child Items into Self"))
action = qtAddAction(menu, self.tr("Merge Child Items into Self"))
action.triggered.connect(qtLambda(self._tree.mergeDocuments, self._handle, False))
action = menu.addAction(self.tr("Merge Child Items into New"))
action = qtAddAction(menu, self.tr("Merge Child Items into New"))
action.triggered.connect(qtLambda(self._tree.mergeDocuments, self._handle, True))
if self._children and isFolder:
action = menu.addAction(self.tr("Merge Documents in Folder"))
action = qtAddAction(menu, self.tr("Merge Documents in Folder"))
action.triggered.connect(qtLambda(self._tree.mergeDocuments, self._handle, True))
if isFile:
action = menu.addAction(self.tr("Split Document by Headings"))
action = qtAddAction(menu, self.tr("Split Document by Headings"))
action.triggered.connect(qtLambda(self._tree.splitDocument, self._handle))
return
def _expandCollapse(self) -> None:
"""Add actions for expand and collapse."""
action = self.addAction(self.tr("Expand All"))
action = qtAddAction(self, self.tr("Expand All"))
action.triggered.connect(qtLambda(self._tree.expandFromIndex, self._indices[0]))
action = self.addAction(self.tr("Collapse All"))
action = qtAddAction(self, self.tr("Collapse All"))
action.triggered.connect(qtLambda(self._tree.collapseFromIndex, self._indices[0]))
return
@@ -1336,7 +1340,7 @@ class _TreeContextMenu(QMenu):
text = self.tr("Delete Permanently")
else:
text = self.tr("Move to Trash")
action = self.addAction(text)
action = qtAddAction(self, text)
action.triggered.connect(self._tree.processDeleteRequest)
return
+18 -22
View File
@@ -28,14 +28,14 @@ import logging
from time import time
from PyQt6.QtCore import Qt, pyqtSignal, pyqtSlot
from PyQt6.QtGui import QCursor, QKeyEvent
from PyQt6.QtGui import QAction, QCursor, QKeyEvent
from PyQt6.QtWidgets import (
QApplication, QFrame, QHBoxLayout, QLabel, QLineEdit, QToolBar,
QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
)
from novelwriter import CONFIG, SHARED
from novelwriter.common import checkInt, cssCol
from novelwriter.common import checkInt, cssCol, qtAddAction
from novelwriter.core.coretools import DocSearch
from novelwriter.core.item import NWItem
from novelwriter.types import (
@@ -65,8 +65,6 @@ class GuiProjectSearch(QWidget):
iPx = SHARED.theme.baseIconHeight
iSz = SHARED.theme.baseIconSize
mPx = CONFIG.pxInt(2)
tPx = CONFIG.pxInt(4)
self._time = time()
self._search = DocSearch()
@@ -76,7 +74,7 @@ class GuiProjectSearch(QWidget):
# Header
self.viewLabel = QLabel(self.tr("Project Search"), self)
self.viewLabel.setFont(SHARED.theme.guiFontB)
self.viewLabel.setContentsMargins(mPx, tPx, 0, mPx)
self.viewLabel.setContentsMargins(2, 4, 0, 2)
# Options
self.searchOpt = QToolBar(self)
@@ -84,30 +82,30 @@ class GuiProjectSearch(QWidget):
self.searchOpt.setIconSize(iSz)
self.searchOpt.setContentsMargins(0, 0, 0, 0)
self.toggleCase = self.searchOpt.addAction(self.tr("Case Sensitive"))
self.toggleCase = qtAddAction(self.searchOpt, self.tr("Case Sensitive"))
self.toggleCase.setCheckable(True)
self.toggleCase.setChecked(CONFIG.searchProjCase)
self.toggleCase.toggled.connect(self._toggleCase)
self.toggleWord = self.searchOpt.addAction(self.tr("Whole Words Only"))
self.toggleWord = qtAddAction(self.searchOpt, self.tr("Whole Words Only"))
self.toggleWord.setCheckable(True)
self.toggleWord.setChecked(CONFIG.searchProjWord)
self.toggleWord.toggled.connect(self._toggleWord)
self.toggleRegEx = self.searchOpt.addAction(self.tr("RegEx Mode"))
self.toggleRegEx = qtAddAction(self.searchOpt, self.tr("RegEx Mode"))
self.toggleRegEx.setCheckable(True)
self.toggleRegEx.setChecked(CONFIG.searchProjRegEx)
self.toggleRegEx.toggled.connect(self._toggleRegEx)
# Search Box
self.searchAction = QAction("", self)
self.searchAction.setIcon(SHARED.theme.getIcon("search", "blue"))
self.searchAction.triggered.connect(self._processSearch)
self.searchText = QLineEdit(self)
self.searchText.setPlaceholderText(self.tr("Search for"))
self.searchText.setClearButtonEnabled(True)
self.searchAction = self.searchText.addAction(
SHARED.theme.getIcon("search", "blue"), QLineEdit.ActionPosition.TrailingPosition
)
self.searchAction.triggered.connect(self._processSearch)
self.searchText.addAction(self.searchAction, QLineEdit.ActionPosition.TrailingPosition)
# Search Result
self.searchResult = QTreeWidget(self)
@@ -121,10 +119,10 @@ class GuiProjectSearch(QWidget):
self.searchResult.itemDoubleClicked.connect(self._searchResultDoubleClicked)
self.searchResult.itemSelectionChanged.connect(self._searchResultSelected)
treeHeader = self.searchResult.header()
treeHeader.setStretchLastSection(False)
treeHeader.setSectionResizeMode(self.C_NAME, QtHeaderStretch)
treeHeader.setSectionResizeMode(self.C_COUNT, QtHeaderToContents)
if header := self.searchResult.header():
header.setStretchLastSection(False)
header.setSectionResizeMode(self.C_NAME, QtHeaderStretch)
header.setSectionResizeMode(self.C_COUNT, QtHeaderToContents)
# Assemble
self.headerBox = QHBoxLayout()
@@ -138,7 +136,7 @@ class GuiProjectSearch(QWidget):
self.outerBox.addWidget(self.searchText, 0)
self.outerBox.addWidget(self.searchResult, 1)
self.outerBox.setContentsMargins(0, 0, 0, 0)
self.outerBox.setSpacing(mPx)
self.outerBox.setSpacing(2)
self.setLayout(self.outerBox)
self.updateTheme()
@@ -153,8 +151,6 @@ class GuiProjectSearch(QWidget):
def updateTheme(self) -> None:
"""Update theme elements."""
bPx = CONFIG.pxInt(1)
mPx = CONFIG.pxInt(2)
qPalette = self.palette()
colBase = cssCol(qPalette.base().color())
@@ -162,8 +158,8 @@ class GuiProjectSearch(QWidget):
self.setStyleSheet(
"QToolBar {padding: 0; background: none;} "
f"QLineEdit {{border: {bPx}px solid {colBase}; padding: {mPx}px;}} "
f"QLineEdit:focus {{border: {bPx}px solid {colFocus};}} "
f"QLineEdit {{border: 1px solid {colBase}; padding: 2px;}} "
f"QLineEdit:focus {{border: 1px solid {colFocus};}} "
)
self.searchAction.setIcon(SHARED.theme.getIcon("search", "blue"))
+2 -2
View File
@@ -31,7 +31,7 @@ from PyQt6.QtCore import QEvent, QPoint, QSize, pyqtSignal
from PyQt6.QtGui import QPalette
from PyQt6.QtWidgets import QMenu, QVBoxLayout, QWidget
from novelwriter import CONFIG, SHARED
from novelwriter import SHARED
from novelwriter.common import qtLambda
from novelwriter.enum import nwView
from novelwriter.extensions.eventfilters import StatusTipFilter
@@ -114,7 +114,7 @@ class GuiSideBar(QWidget):
self.outerBox.addWidget(self.tbStats)
self.outerBox.addWidget(self.tbSettings)
self.outerBox.setContentsMargins(0, 0, 0, 0)
self.outerBox.setSpacing(CONFIG.pxInt(6))
self.outerBox.setSpacing(6)
self.setLayout(self.outerBox)
self.updateTheme()
+4 -6
View File
@@ -57,13 +57,11 @@ class GuiMainStatus(QStatusBar):
# Permanent Widgets
# =================
xM = CONFIG.pxInt(8)
# The Spell Checker Language
self.langIcon = QLabel("", self)
self.langText = QLabel(self.tr("None"), self)
self.langIcon.setContentsMargins(0, 0, 0, 0)
self.langText.setContentsMargins(0, 0, xM, 0)
self.langText.setContentsMargins(0, 0, 8, 0)
self.addPermanentWidget(self.langIcon)
self.addPermanentWidget(self.langText)
@@ -71,7 +69,7 @@ class GuiMainStatus(QStatusBar):
self.docIcon = StatusLED(iPx, iPx, self)
self.docText = QLabel(self.tr("Editor"), self)
self.docIcon.setContentsMargins(0, 0, 0, 0)
self.docText.setContentsMargins(0, 0, xM, 0)
self.docText.setContentsMargins(0, 0, 8, 0)
self.addPermanentWidget(self.docIcon)
self.addPermanentWidget(self.docText)
@@ -79,7 +77,7 @@ class GuiMainStatus(QStatusBar):
self.projIcon = StatusLED(iPx, iPx, self)
self.projText = QLabel(self.tr("Project"), self)
self.projIcon.setContentsMargins(0, 0, 0, 0)
self.projText.setContentsMargins(0, 0, xM, 0)
self.projText.setContentsMargins(0, 0, 8, 0)
self.addPermanentWidget(self.projIcon)
self.addPermanentWidget(self.projText)
@@ -87,7 +85,7 @@ class GuiMainStatus(QStatusBar):
self.statsIcon = QLabel(self)
self.statsText = QLabel("", self)
self.statsIcon.setContentsMargins(0, 0, 0, 0)
self.statsText.setContentsMargins(0, 0, xM, 0)
self.statsText.setContentsMargins(0, 0, 8, 0)
self.addPermanentWidget(self.statsIcon)
self.addPermanentWidget(self.statsText)
+3 -8
View File
@@ -544,31 +544,26 @@ class GuiTheme:
"""Build default style sheets."""
self._styleSheets = {}
aPx = CONFIG.pxInt(2)
bPx = CONFIG.pxInt(4)
cPx = CONFIG.pxInt(6)
dPx = CONFIG.pxInt(8)
tCol = palette.text().color()
hCol = palette.highlight().color()
# Flat Tab Widget and Tab Bar:
self._styleSheets[STYLES_FLAT_TABS] = (
"QTabWidget::pane {border: 0;} "
f"QTabWidget QTabBar::tab {{border: 0; padding: {bPx}px {dPx}px;}} "
"QTabWidget QTabBar::tab {border: 0; padding: 4px 8px;} "
f"QTabWidget QTabBar::tab:selected {{color: {cssCol(hCol)};}} "
)
# Minimal Tool Button
self._styleSheets[STYLES_MIN_TOOLBUTTON] = (
f"QToolButton {{padding: {aPx}px; margin: 0; border: none; background: transparent;}} "
"QToolButton {padding: 2px; margin: 0; border: none; background: transparent;} "
f"QToolButton:hover {{border: none; background: {cssCol(tCol, 48)};}} "
"QToolButton::menu-indicator {image: none;} "
)
# Big Tool Button
self._styleSheets[STYLES_BIG_TOOLBUTTON] = (
f"QToolButton {{padding: {cPx}px; margin: 0; border: none; background: transparent;}} "
"QToolButton {padding: 6px; margin: 0; border: none; background: transparent;} "
f"QToolButton:hover {{border: none; background: {cssCol(tCol, 48)};}} "
"QToolButton::menu-indicator {image: none;} "
)