Change main menu to emit signals

This commit is contained in:
Veronica Berglyd Olsen
2023-11-08 18:00:43 +01:00
parent 1a6072be2c
commit 711766cf52
6 changed files with 324 additions and 123 deletions
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.1" viewBox="0 0 6.35 6.35" xmlns="http://www.w3.org/2000/svg">
<path d="m1.9519 3.0221-0.16749 0.58257h1.2161l-0.16749-0.58257q-0.11651-0.37867-0.22575-0.77919-0.10195-0.40052-0.2039-0.79375h-0.029128q-0.10195 0.40052-0.2039 0.80103-0.10195 0.39323-0.21846 0.7719zm-1.5948 2.5342 1.5511-4.7625h0.99037l1.5511 4.7625h-0.88842l-0.37139-1.2889h-1.6021l-0.37139 1.2889z" fill-opacity=".78039" stroke-opacity=".78039" stroke-width=".54616"/>
<path d="m4.4491 5.5562v-2.1167h0.67643q0.16506 0 0.30099 0.029128 0.13917 0.025892 0.2395 0.087385 0.10357 0.058257 0.15859 0.15859 0.058257 0.10033 0.058257 0.24597 0 0.15212-0.077675 0.28157-0.077675 0.12946-0.21684 0.17801v0.012947q0.17477 0.038837 0.28805 0.16506 0.11651 0.12299 0.11651 0.3366 0 0.15859-0.061493 0.2751-0.061493 0.11651-0.17153 0.19419-0.10681 0.077675-0.25568 0.11651-0.14888 0.035601-0.32365 0.035601zm0.37543-1.2428h0.26863q0.22332 0 0.32041-0.080912 0.10033-0.080912 0.10033-0.21684 0-0.15535-0.10357-0.22008-0.10357-0.064729-0.3107-0.064729h-0.2751zm0 0.95153h0.31718q0.23303 0 0.35925-0.084149 0.12622-0.087385 0.12622-0.26539 0-0.1683-0.12299-0.24274-0.12299-0.077676-0.36249-0.077676h-0.31718z" fill-opacity=".78039" stroke-opacity=".78039" stroke-width=".24274"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.1" viewBox="0 0 6.35 6.35" xmlns="http://www.w3.org/2000/svg">
<path d="m2.1082 3.0221-0.16749 0.58257h1.2161l-0.16749-0.58257q-0.11651-0.37867-0.22575-0.77919-0.10195-0.40052-0.2039-0.79375h-0.029128q-0.10195 0.40052-0.2039 0.80103-0.10195 0.39323-0.21846 0.7719zm-1.5948 2.5342 1.5511-4.7625h0.99037l1.5511 4.7625h-0.88842l-0.37139-1.2889h-1.6021l-0.37139 1.2889z" fill-opacity=".78039" stroke-opacity=".78039" stroke-width=".54616"/>
<path d="m4.2928 2.9104v-2.1167h0.67642q0.16507 0 0.301 0.029128 0.13917 0.025892 0.2395 0.087385 0.10357 0.058257 0.15859 0.15859 0.058257 0.10033 0.058257 0.24597 0 0.15212-0.077674 0.28157-0.077674 0.12946-0.21684 0.17801v0.012947q0.17477 0.038837 0.28805 0.16507 0.11651 0.12299 0.11651 0.3366 0 0.15859-0.061493 0.2751-0.061493 0.11651-0.17153 0.19418-0.1068 0.077674-0.25568 0.11651-0.14888 0.035601-0.32365 0.035601zm0.37544-1.2428h0.26862q0.22332 0 0.32041-0.080912 0.10033-0.080911 0.10033-0.21684 0-0.15535-0.10357-0.22008-0.10357-0.064728-0.3107-0.064728h-0.2751zm0 0.95153h0.31717q0.23303 0 0.35925-0.084149 0.12622-0.087385 0.12622-0.26538 0-0.16829-0.12299-0.24273-0.12299-0.077675-0.36249-0.077675h-0.31717z" fill-opacity=".78039" stroke-opacity=".78039" stroke-width=".24273"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

+18 -12
View File
@@ -178,9 +178,11 @@ class Config:
self.spellLanguage = "en"
# State
self.showRefPanel = True # The reference panel for the viewer is visible
self.viewComments = True # Comments are shown in the viewer
self.viewSynopsis = True # Synopsis is shown in the viewer
self.showRefPanel = True # The reference panel for the viewer is visible
self.showEditToolBar = False # The document editor toolbar visibility
self.useShortcodes = False # Use shorcodes for basic formatting
self.viewComments = True # Comments are shown in the viewer
self.viewSynopsis = True # Synopsis is shown in the viewer
# Search Bar Switches
self.searchCase = False
@@ -598,15 +600,17 @@ class Config:
# State
sec = "State"
self.showRefPanel = conf.rdBool(sec, "showrefpanel", self.showRefPanel)
self.viewComments = conf.rdBool(sec, "viewcomments", self.viewComments)
self.viewSynopsis = conf.rdBool(sec, "viewsynopsis", self.viewSynopsis)
self.searchCase = conf.rdBool(sec, "searchcase", self.searchCase)
self.searchWord = conf.rdBool(sec, "searchword", self.searchWord)
self.searchRegEx = conf.rdBool(sec, "searchregex", self.searchRegEx)
self.searchLoop = conf.rdBool(sec, "searchloop", self.searchLoop)
self.searchNextFile = conf.rdBool(sec, "searchnextfile", self.searchNextFile)
self.searchMatchCap = conf.rdBool(sec, "searchmatchcap", self.searchMatchCap)
self.showRefPanel = conf.rdBool(sec, "showrefpanel", self.showRefPanel)
self.showEditToolBar = conf.rdBool(sec, "showedittoolbar", self.showEditToolBar)
self.useShortcodes = conf.rdBool(sec, "useshortcodes", self.useShortcodes)
self.viewComments = conf.rdBool(sec, "viewcomments", self.viewComments)
self.viewSynopsis = conf.rdBool(sec, "viewsynopsis", self.viewSynopsis)
self.searchCase = conf.rdBool(sec, "searchcase", self.searchCase)
self.searchWord = conf.rdBool(sec, "searchword", self.searchWord)
self.searchRegEx = conf.rdBool(sec, "searchregex", self.searchRegEx)
self.searchLoop = conf.rdBool(sec, "searchloop", self.searchLoop)
self.searchNextFile = conf.rdBool(sec, "searchnextfile", self.searchNextFile)
self.searchMatchCap = conf.rdBool(sec, "searchmatchcap", self.searchMatchCap)
# Deprecated Settings or Locations as of 2.0
# ToDo: These will be loaded for a few minor releases until the users have converted them
@@ -721,6 +725,8 @@ class Config:
conf["State"] = {
"showrefpanel": str(self.showRefPanel),
"showedittoolbar": str(self.showEditToolBar),
"useshortcodes": str(self.useShortcodes),
"viewcomments": str(self.viewComments),
"viewsynopsis": str(self.viewSynopsis),
"searchcase": str(self.searchCase),
+84 -22
View File
@@ -138,9 +138,12 @@ class GuiDocEditor(QPlainTextEdit):
self.docFooter = GuiDocEditFooter(self)
self.docSearch = GuiDocEditSearch(self)
self.docToolBar = GuiDocToolBar(self)
self.docToolBar.setVisible(CONFIG.showEditToolBar)
# Connect Signals
self.docHeader.closeDocumentRequest.connect(self._closeCurrentDocument)
self.docHeader.toggleToolBarRequest.connect(self._toggleToolBarVisibility)
self.docToolBar.requestDocAction.connect(self.docAction)
# Context Menu
self.setContextMenuPolicy(Qt.CustomContextMenu)
@@ -849,31 +852,11 @@ class GuiDocEditor(QPlainTextEdit):
return True
def insertKeyWord(self, keyword: str) -> bool:
"""Insert a keyword in the text editor, at the cursor position.
If the insert line is not blank, a new line is started.
"""
if keyword not in nwKeyWords.VALID_KEYS:
logger.error("Invalid keyword '%s'", keyword)
return False
logger.debug("Inserting keyword '%s'", keyword)
state = self.insertNewBlock("%s: " % keyword)
return state
def closeSearch(self) -> bool:
"""Close the search box."""
self.docSearch.closeSearch()
return self.docSearch.isVisible()
@pyqtSlot()
def toggleSearch(self) -> None:
"""Toggle the visibility of the search box."""
if self.docSearch.isVisible():
self.docSearch.closeSearch()
else:
self.beginSearch()
return
##
# Document Events and Maintenance
##
@@ -968,6 +951,27 @@ class GuiDocEditor(QPlainTextEdit):
self.updateDocMargins()
return
@pyqtSlot(str)
def insertKeyWord(self, keyword: str) -> bool:
"""Insert a keyword in the text editor, at the cursor position.
If the insert line is not blank, a new line is started.
"""
if keyword not in nwKeyWords.VALID_KEYS:
logger.error("Invalid keyword '%s'", keyword)
return False
logger.debug("Inserting keyword '%s'", keyword)
state = self.insertNewBlock("%s: " % keyword)
return state
@pyqtSlot()
def toggleSearch(self) -> None:
"""Toggle the visibility of the search box."""
if self.docSearch.isVisible():
self.docSearch.closeSearch()
else:
self.beginSearch()
return
##
# Private Slots
##
@@ -1194,6 +1198,14 @@ class GuiDocEditor(QPlainTextEdit):
self.closeDocumentRequest.emit()
return
@pyqtSlot()
def _toggleToolBarVisibility(self) -> None:
"""Toggle the visibility of the tool bar."""
state = not self.docToolBar.isVisible()
self.docToolBar.setVisible(state)
CONFIG.showEditToolBar = state
return
##
# Search & Replace
##
@@ -2094,6 +2106,8 @@ class BackgroundWordCounterSignals(QObject):
class GuiDocToolBar(QWidget):
requestDocAction = pyqtSignal(nwDocAction)
def __init__(self, docEditor: GuiDocEditor) -> None:
super().__init__(parent=docEditor)
@@ -2108,26 +2122,41 @@ class GuiDocToolBar(QWidget):
# ===============
self.tbMode = QToolButton(self)
self.tbMode.setToolTip(self.tr("Toggle Markdown or Shortcodes Mode"))
self.tbMode.setIconSize(iconSize)
self.tbMode.setCheckable(True)
self.tbMode.setChecked(CONFIG.useShortcodes)
self.tbMode.toggled.connect(self._toggleFormatMode)
self.tbBold = QToolButton(self)
self.tbBold.setIconSize(iconSize)
self.tbBold.clicked.connect(self._formatBold)
self.tbItalic = QToolButton(self)
self.tbItalic.setIconSize(iconSize)
self.tbItalic.clicked.connect(self._formatItalic)
self.tbStrike = QToolButton(self)
self.tbStrike.setIconSize(iconSize)
self.tbStrike.clicked.connect(self._formatStrike)
self.tbUnderline = QToolButton(self)
self.tbUnderline.setIconSize(iconSize)
self.tbUnderline.clicked.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_ULINE)
)
self.tbSuperscript = QToolButton(self)
self.tbSuperscript.setIconSize(iconSize)
self.tbSuperscript.clicked.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_SUP)
)
self.tbSubscript = QToolButton(self)
self.tbSubscript.setIconSize(iconSize)
self.tbSubscript.clicked.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_SUB)
)
# Assemble
# ========
@@ -2156,7 +2185,6 @@ class GuiDocToolBar(QWidget):
palette.setColor(QPalette.Window, QColor(*SHARED.theme.colBack))
palette.setColor(QPalette.WindowText, QColor(*SHARED.theme.colText))
palette.setColor(QPalette.Text, QColor(*SHARED.theme.colText))
self.setPalette(palette)
# qPalette = self.palette()
@@ -2182,6 +2210,40 @@ class GuiDocToolBar(QWidget):
return
##
# Internal Slots
##
@pyqtSlot(bool)
def _toggleFormatMode(self, checked: bool) -> None:
"""Toggle the formatting mode."""
CONFIG.useShortcodes = checked
return
@pyqtSlot()
def _formatBold(self):
"""Call the bold format action."""
self.requestDocAction.emit(
nwDocAction.SC_BOLD if self.tbMode.isChecked() else nwDocAction.STRONG
)
return
@pyqtSlot()
def _formatItalic(self):
"""Call the italic format action."""
self.requestDocAction.emit(
nwDocAction.SC_ITALIC if self.tbMode.isChecked() else nwDocAction.EMPH
)
return
@pyqtSlot()
def _formatStrike(self):
"""Call the strikethrough format action."""
self.requestDocAction.emit(
nwDocAction.SC_STRIKE if self.tbMode.isChecked() else nwDocAction.STRIKE
)
return
# END Class GuiDocToolBar
@@ -2600,8 +2662,8 @@ class GuiDocEditSearch(QFrame):
class GuiDocEditHeader(QWidget):
toggleToolBarRequest = pyqtSignal()
closeDocumentRequest = pyqtSignal()
toggleToolBarRequest = pyqtSignal()
def __init__(self, docEditor: GuiDocEditor) -> None:
super().__init__(parent=docEditor)
+182 -74
View File
@@ -30,7 +30,7 @@ from pathlib import Path
from urllib.parse import urljoin
from urllib.request import pathname2url
from PyQt5.QtCore import QUrl, pyqtSlot
from PyQt5.QtCore import QUrl, pyqtSignal, pyqtSlot
from PyQt5.QtGui import QDesktopServices
from PyQt5.QtWidgets import QMenuBar, QAction
@@ -50,6 +50,11 @@ class GuiMainMenu(QMenuBar):
add them from this class.
"""
requestDocAction = pyqtSignal(nwDocAction)
requestDocInsert = pyqtSignal(nwDocInsert)
requestDocInsertText = pyqtSignal(str)
requestDocKeyWordInsert = pyqtSignal(str)
def __init__(self, mainGui: GuiMain) -> None:
super().__init__(parent=mainGui)
@@ -68,11 +73,6 @@ class GuiMainMenu(QMenuBar):
self._buildToolsMenu()
self._buildHelpMenu()
# Function Pointers
self._docAction = self.mainGui.passDocumentAction
self._docInsert = self.mainGui.docEditor.insertText
self._insertKeyWord = self.mainGui.docEditor.insertKeyWord
logger.debug("Ready: GuiMainMenu")
return
@@ -246,12 +246,12 @@ class GuiMainMenu(QMenuBar):
# Edit > Undo
self.aEditUndo = self.editMenu.addAction(self.tr("Undo"))
self.aEditUndo.setShortcut("Ctrl+Z")
self.aEditUndo.triggered.connect(lambda: self._docAction(nwDocAction.UNDO))
self.aEditUndo.triggered.connect(lambda: self.requestDocAction.emit(nwDocAction.UNDO))
# Edit > Redo
self.aEditRedo = self.editMenu.addAction(self.tr("Redo"))
self.aEditRedo.setShortcut("Ctrl+Y")
self.aEditRedo.triggered.connect(lambda: self._docAction(nwDocAction.REDO))
self.aEditRedo.triggered.connect(lambda: self.requestDocAction.emit(nwDocAction.REDO))
# Edit > Separator
self.editMenu.addSeparator()
@@ -259,17 +259,17 @@ class GuiMainMenu(QMenuBar):
# Edit > Cut
self.aEditCut = self.editMenu.addAction(self.tr("Cut"))
self.aEditCut.setShortcut("Ctrl+X")
self.aEditCut.triggered.connect(lambda: self._docAction(nwDocAction.CUT))
self.aEditCut.triggered.connect(lambda: self.requestDocAction.emit(nwDocAction.CUT))
# Edit > Copy
self.aEditCopy = self.editMenu.addAction(self.tr("Copy"))
self.aEditCopy.setShortcut("Ctrl+C")
self.aEditCopy.triggered.connect(lambda: self._docAction(nwDocAction.COPY))
self.aEditCopy.triggered.connect(lambda: self.requestDocAction.emit(nwDocAction.COPY))
# Edit > Paste
self.aEditPaste = self.editMenu.addAction(self.tr("Paste"))
self.aEditPaste.setShortcut("Ctrl+V")
self.aEditPaste.triggered.connect(lambda: self._docAction(nwDocAction.PASTE))
self.aEditPaste.triggered.connect(lambda: self.requestDocAction.emit(nwDocAction.PASTE))
# Edit > Separator
self.editMenu.addSeparator()
@@ -277,12 +277,12 @@ class GuiMainMenu(QMenuBar):
# Edit > Select All
self.aSelectAll = self.editMenu.addAction(self.tr("Select All"))
self.aSelectAll.setShortcut("Ctrl+A")
self.aSelectAll.triggered.connect(lambda: self._docAction(nwDocAction.SEL_ALL))
self.aSelectAll.triggered.connect(lambda: self.requestDocAction.emit(nwDocAction.SEL_ALL))
# Edit > Select Paragraph
self.aSelectPar = self.editMenu.addAction(self.tr("Select Paragraph"))
self.aSelectPar.setShortcut("Ctrl+Shift+A")
self.aSelectPar.triggered.connect(lambda: self._docAction(nwDocAction.SEL_PARA))
self.aSelectPar.triggered.connect(lambda: self.requestDocAction.emit(nwDocAction.SEL_PARA))
return
@@ -350,22 +350,30 @@ class GuiMainMenu(QMenuBar):
# Insert > Short Dash
self.aInsENDash = self.mInsDashes.addAction(self.tr("Short Dash"))
self.aInsENDash.setShortcut("Ctrl+K, -")
self.aInsENDash.triggered.connect(lambda: self._docInsert(nwUnicode.U_ENDASH))
self.aInsENDash.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_ENDASH)
)
# Insert > Long Dash
self.aInsEMDash = self.mInsDashes.addAction(self.tr("Long Dash"))
self.aInsEMDash.setShortcut("Ctrl+K, _")
self.aInsEMDash.triggered.connect(lambda: self._docInsert(nwUnicode.U_EMDASH))
self.aInsEMDash.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_EMDASH)
)
# Insert > Long Dash
self.aInsHorBar = self.mInsDashes.addAction(self.tr("Horizontal Bar"))
self.aInsHorBar.setShortcut("Ctrl+K, Ctrl+_")
self.aInsHorBar.triggered.connect(lambda: self._docInsert(nwUnicode.U_HBAR))
self.aInsHorBar.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_HBAR)
)
# Insert > Figure Dash
self.aInsFigDash = self.mInsDashes.addAction(self.tr("Figure Dash"))
self.aInsFigDash.setShortcut("Ctrl+K, ~")
self.aInsFigDash.triggered.connect(lambda: self._docInsert(nwUnicode.U_FGDASH))
self.aInsFigDash.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_FGDASH)
)
# Insert > Quote Marks
self.mInsQuotes = self.insMenu.addMenu(self.tr("Quote Marks"))
@@ -373,27 +381,37 @@ class GuiMainMenu(QMenuBar):
# Insert > Left Single Quote
self.aInsQuoteLS = self.mInsQuotes.addAction(self.tr("Left Single Quote"))
self.aInsQuoteLS.setShortcut("Ctrl+K, 1")
self.aInsQuoteLS.triggered.connect(lambda: self._docInsert(nwDocInsert.QUOTE_LS))
self.aInsQuoteLS.triggered.connect(
lambda: self.requestDocInsert.emit(nwDocInsert.QUOTE_LS)
)
# Insert > Right Single Quote
self.aInsQuoteRS = self.mInsQuotes.addAction(self.tr("Right Single Quote"))
self.aInsQuoteRS.setShortcut("Ctrl+K, 2")
self.aInsQuoteRS.triggered.connect(lambda: self._docInsert(nwDocInsert.QUOTE_RS))
self.aInsQuoteRS.triggered.connect(
lambda: self.requestDocInsert.emit(nwDocInsert.QUOTE_RS)
)
# Insert > Left Double Quote
self.aInsQuoteLD = self.mInsQuotes.addAction(self.tr("Left Double Quote"))
self.aInsQuoteLD.setShortcut("Ctrl+K, 3")
self.aInsQuoteLD.triggered.connect(lambda: self._docInsert(nwDocInsert.QUOTE_LD))
self.aInsQuoteLD.triggered.connect(
lambda: self.requestDocInsert.emit(nwDocInsert.QUOTE_LD)
)
# Insert > Right Double Quote
self.aInsQuoteRD = self.mInsQuotes.addAction(self.tr("Right Double Quote"))
self.aInsQuoteRD.setShortcut("Ctrl+K, 4")
self.aInsQuoteRD.triggered.connect(lambda: self._docInsert(nwDocInsert.QUOTE_RD))
self.aInsQuoteRD.triggered.connect(
lambda: self.requestDocInsert.emit(nwDocInsert.QUOTE_RD)
)
# Insert > Alternative Apostrophe
self.aInsMSApos = self.mInsQuotes.addAction(self.tr("Alternative Apostrophe"))
self.aInsMSApos.setShortcut("Ctrl+K, '")
self.aInsMSApos.triggered.connect(lambda: self._docInsert(nwUnicode.U_MAPOSS))
self.aInsMSApos.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_MAPOSS)
)
# Insert > Symbols
self.mInsPunct = self.insMenu.addMenu(self.tr("General Punctuation"))
@@ -401,17 +419,23 @@ class GuiMainMenu(QMenuBar):
# Insert > Ellipsis
self.aInsEllipsis = self.mInsPunct.addAction(self.tr("Ellipsis"))
self.aInsEllipsis.setShortcut("Ctrl+K, .")
self.aInsEllipsis.triggered.connect(lambda: self._docInsert(nwUnicode.U_HELLIP))
self.aInsEllipsis.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_HELLIP)
)
# Insert > Prime
self.aInsPrime = self.mInsPunct.addAction(self.tr("Prime"))
self.aInsPrime.setShortcut("Ctrl+K, Ctrl+'")
self.aInsPrime.triggered.connect(lambda: self._docInsert(nwUnicode.U_PRIME))
self.aInsPrime.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_PRIME)
)
# Insert > Double Prime
self.aInsDPrime = self.mInsPunct.addAction(self.tr("Double Prime"))
self.aInsDPrime.setShortcut("Ctrl+K, Ctrl+\"")
self.aInsDPrime.triggered.connect(lambda: self._docInsert(nwUnicode.U_DPRIME))
self.aInsDPrime.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_DPRIME)
)
# Insert > White Spaces
self.mInsSpace = self.insMenu.addMenu(self.tr("White Spaces"))
@@ -419,17 +443,23 @@ class GuiMainMenu(QMenuBar):
# Insert > Non-Breaking Space
self.aInsNBSpace = self.mInsSpace.addAction(self.tr("Non-Breaking Space"))
self.aInsNBSpace.setShortcut("Ctrl+K, Space")
self.aInsNBSpace.triggered.connect(lambda: self._docInsert(nwUnicode.U_NBSP))
self.aInsNBSpace.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_NBSP)
)
# Insert > Thin Space
self.aInsThinSpace = self.mInsSpace.addAction(self.tr("Thin Space"))
self.aInsThinSpace.setShortcut("Ctrl+K, Shift+Space")
self.aInsThinSpace.triggered.connect(lambda: self._docInsert(nwUnicode.U_THSP))
self.aInsThinSpace.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_THSP)
)
# Insert > Thin Non-Breaking Space
self.aInsThinNBSpace = self.mInsSpace.addAction(self.tr("Thin Non-Breaking Space"))
self.aInsThinNBSpace.setShortcut("Ctrl+K, Ctrl+Space")
self.aInsThinNBSpace.triggered.connect(lambda: self._docInsert(nwUnicode.U_THNBSP))
self.aInsThinNBSpace.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_THNBSP)
)
# Insert > Symbols
self.mInsSymbol = self.insMenu.addMenu(self.tr("Other Symbols"))
@@ -437,42 +467,58 @@ class GuiMainMenu(QMenuBar):
# Insert > List Bullet
self.aInsBullet = self.mInsSymbol.addAction(self.tr("List Bullet"))
self.aInsBullet.setShortcut("Ctrl+K, *")
self.aInsBullet.triggered.connect(lambda: self._docInsert(nwUnicode.U_BULL))
self.aInsBullet.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_BULL)
)
# Insert > Hyphen Bullet
self.aInsHyBull = self.mInsSymbol.addAction(self.tr("Hyphen Bullet"))
self.aInsHyBull.setShortcut("Ctrl+K, Ctrl+-")
self.aInsHyBull.triggered.connect(lambda: self._docInsert(nwUnicode.U_HYBULL))
self.aInsHyBull.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_HYBULL)
)
# Insert > Flower Mark
self.aInsFlower = self.mInsSymbol.addAction(self.tr("Flower Mark"))
self.aInsFlower.setShortcut("Ctrl+K, Ctrl+*")
self.aInsFlower.triggered.connect(lambda: self._docInsert(nwUnicode.U_FLOWER))
self.aInsFlower.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_FLOWER)
)
# Insert > Per Mille
self.aInsPerMille = self.mInsSymbol.addAction(self.tr("Per Mille"))
self.aInsPerMille.setShortcut("Ctrl+K, %")
self.aInsPerMille.triggered.connect(lambda: self._docInsert(nwUnicode.U_PERMIL))
self.aInsPerMille.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_PERMIL)
)
# Insert > Degree Symbol
self.aInsDegree = self.mInsSymbol.addAction(self.tr("Degree Symbol"))
self.aInsDegree.setShortcut("Ctrl+K, Ctrl+O")
self.aInsDegree.triggered.connect(lambda: self._docInsert(nwUnicode.U_DEGREE))
self.aInsDegree.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_DEGREE)
)
# Insert > Minus Sign
self.aInsMinus = self.mInsSymbol.addAction(self.tr("Minus Sign"))
self.aInsMinus.setShortcut("Ctrl+K, Ctrl+M")
self.aInsMinus.triggered.connect(lambda: self._docInsert(nwUnicode.U_MINUS))
self.aInsMinus.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_MINUS)
)
# Insert > Times Sign
self.aInsTimes = self.mInsSymbol.addAction(self.tr("Times Sign"))
self.aInsTimes.setShortcut("Ctrl+K, Ctrl+X")
self.aInsTimes.triggered.connect(lambda: self._docInsert(nwUnicode.U_TIMES))
self.aInsTimes.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_TIMES)
)
# Insert > Division
self.aInsDivide = self.mInsSymbol.addAction(self.tr("Division Sign"))
self.aInsDivide.setShortcut("Ctrl+K, Ctrl+D")
self.aInsDivide.triggered.connect(lambda: self._docInsert(nwUnicode.U_DIVIDE))
self.aInsDivide.triggered.connect(
lambda: self.requestDocInsertText.emit(nwUnicode.U_DIVIDE)
)
# Insert > Tags and References
self.mInsKeywords = self.insMenu.addMenu(self.tr("Tags and References"))
@@ -491,7 +537,7 @@ class GuiMainMenu(QMenuBar):
self.mInsKWItems[keyWord][0].setText(trConst(nwLabels.KEY_NAME[keyWord]))
self.mInsKWItems[keyWord][0].setShortcut(self.mInsKWItems[keyWord][1])
self.mInsKWItems[keyWord][0].triggered.connect(
lambda n, keyWord=keyWord: self._insertKeyWord(keyWord)
lambda n, keyWord=keyWord: self.requestDocKeyWordInsert.emit(keyWord)
)
self.mInsKeywords.addAction(self.mInsKWItems[keyWord][0])
@@ -501,22 +547,30 @@ class GuiMainMenu(QMenuBar):
# Insert > Synopsis Comment
self.aInsSynopsis = self.mInsComments.addAction(self.tr("Synopsis Comment"))
self.aInsSynopsis.setShortcut("Ctrl+K, S")
self.aInsSynopsis.triggered.connect(lambda: self._docInsert(nwDocInsert.SYNOPSIS))
self.aInsSynopsis.triggered.connect(
lambda: self.requestDocInsert.emit(nwDocInsert.SYNOPSIS)
)
# Insert > Symbols
self.mInsBreaks = self.insMenu.addMenu(self.tr("Page Break and Space"))
# Insert > New Page
self.aInsNewPage = self.mInsBreaks.addAction(self.tr("Page Break"))
self.aInsNewPage.triggered.connect(lambda: self._docInsert(nwDocInsert.NEW_PAGE))
self.aInsNewPage.triggered.connect(
lambda: self.requestDocInsert.emit(nwDocInsert.NEW_PAGE)
)
# Insert > Vertical Space (Single)
self.aInsVSpaceS = self.mInsBreaks.addAction(self.tr("Vertical Space (Single)"))
self.aInsVSpaceS.triggered.connect(lambda: self._docInsert(nwDocInsert.VSPACE_S))
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.triggered.connect(lambda: self._docInsert(nwDocInsert.VSPACE_M))
self.aInsVSpaceM.triggered.connect(
lambda: self.requestDocInsert.emit(nwDocInsert.VSPACE_M)
)
# Insert > Placeholder Text
self.aLipsumText = self.mInsBreaks.addAction(self.tr("Placeholder Text"))
@@ -532,17 +586,23 @@ class GuiMainMenu(QMenuBar):
# Format > Emphasis
self.aFmtEmph = self.fmtMenu.addAction(self.tr("Emphasis"))
self.aFmtEmph.setShortcut("Ctrl+I")
self.aFmtEmph.triggered.connect(lambda: self._docAction(nwDocAction.EMPH))
self.aFmtEmph.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.EMPH)
)
# Format > Strong Emphasis
self.aFmtStrong = self.fmtMenu.addAction(self.tr("Strong Emphasis"))
self.aFmtStrong.setShortcut("Ctrl+B")
self.aFmtStrong.triggered.connect(lambda: self._docAction(nwDocAction.STRONG))
self.aFmtStrong.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.STRONG)
)
# Format > Strikethrough
self.aFmtStrike = self.fmtMenu.addAction(self.tr("Strikethrough"))
self.aFmtStrike.setShortcut("Ctrl+D")
self.aFmtStrike.triggered.connect(lambda: self._docAction(nwDocAction.STRIKE))
self.aFmtStrike.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.STRIKE)
)
# Edit > Separator
self.fmtMenu.addSeparator()
@@ -550,12 +610,16 @@ class GuiMainMenu(QMenuBar):
# Format > Double Quotes
self.aFmtDQuote = self.fmtMenu.addAction(self.tr("Wrap Double Quotes"))
self.aFmtDQuote.setShortcut("Ctrl+\"")
self.aFmtDQuote.triggered.connect(lambda: self._docAction(nwDocAction.D_QUOTE))
self.aFmtDQuote.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.D_QUOTE)
)
# Format > Single Quotes
self.aFmtSQuote = self.fmtMenu.addAction(self.tr("Wrap Single Quotes"))
self.aFmtSQuote.setShortcut("Ctrl+'")
self.aFmtSQuote.triggered.connect(lambda: self._docAction(nwDocAction.S_QUOTE))
self.aFmtSQuote.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.S_QUOTE)
)
# Format > Separator
self.fmtMenu.addSeparator()
@@ -564,28 +628,40 @@ class GuiMainMenu(QMenuBar):
self.mShortcodes = self.fmtMenu.addMenu(self.tr("More Formats ..."))
# Shortcode Italic
self.aScItalic = self.mShortcodes.addAction(self.tr("Italics Shortcode"))
self.aScItalic.triggered.connect(lambda: self._docAction(nwDocAction.SC_ITALIC))
self.aScItalic = self.mShortcodes.addAction(self.tr("Italics (Shortcode)"))
self.aScItalic.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_ITALIC)
)
# Shortcode Bold
self.aScBold = self.mShortcodes.addAction(self.tr("Bold Shortcode"))
self.aScBold.triggered.connect(lambda: self._docAction(nwDocAction.SC_BOLD))
# Shortcode Underline
self.aScULine = self.mShortcodes.addAction(self.tr("Underline Shortcode"))
self.aScULine.triggered.connect(lambda: self._docAction(nwDocAction.SC_ULINE))
self.aScBold = self.mShortcodes.addAction(self.tr("Bold (Shortcode)"))
self.aScBold.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_BOLD)
)
# Shortcode Strikethrough
self.aScStrike = self.mShortcodes.addAction(self.tr("Strikethrough Shortcode"))
self.aScStrike.triggered.connect(lambda: self._docAction(nwDocAction.SC_STRIKE))
self.aScStrike = self.mShortcodes.addAction(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.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_ULINE)
)
# Shortcode Superscript
self.aScSuper = self.mShortcodes.addAction(self.tr("Superscript"))
self.aScSuper.triggered.connect(lambda: self._docAction(nwDocAction.SC_SUP))
self.aScSuper.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_SUP)
)
# Shortcode Subscript
self.aScSub = self.mShortcodes.addAction(self.tr("Subscript"))
self.aScSub.triggered.connect(lambda: self._docAction(nwDocAction.SC_SUB))
self.aScSub.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_SUB)
)
# Format > Separator
self.fmtMenu.addSeparator()
@@ -593,33 +669,45 @@ class GuiMainMenu(QMenuBar):
# Format > Header 1 (Partition)
self.aFmtHead1 = self.fmtMenu.addAction(self.tr("Header 1 (Partition)"))
self.aFmtHead1.setShortcut("Ctrl+1")
self.aFmtHead1.triggered.connect(lambda: self._docAction(nwDocAction.BLOCK_H1))
self.aFmtHead1.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H1)
)
# Format > Header 2 (Chapter)
self.aFmtHead2 = self.fmtMenu.addAction(self.tr("Header 2 (Chapter)"))
self.aFmtHead2.setShortcut("Ctrl+2")
self.aFmtHead2.triggered.connect(lambda: self._docAction(nwDocAction.BLOCK_H2))
self.aFmtHead2.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H2)
)
# Format > Header 3 (Scene)
self.aFmtHead3 = self.fmtMenu.addAction(self.tr("Header 3 (Scene)"))
self.aFmtHead3.setShortcut("Ctrl+3")
self.aFmtHead3.triggered.connect(lambda: self._docAction(nwDocAction.BLOCK_H3))
self.aFmtHead3.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H3)
)
# Format > Header 4 (Section)
self.aFmtHead4 = self.fmtMenu.addAction(self.tr("Header 4 (Section)"))
self.aFmtHead4.setShortcut("Ctrl+4")
self.aFmtHead4.triggered.connect(lambda: self._docAction(nwDocAction.BLOCK_H4))
self.aFmtHead4.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H4)
)
# Format > Separator
self.fmtMenu.addSeparator()
# Format > Novel Title
self.aFmtTitle = self.fmtMenu.addAction(self.tr("Novel Title"))
self.aFmtTitle.triggered.connect(lambda: self._docAction(nwDocAction.BLOCK_TTL))
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.triggered.connect(lambda: self._docAction(nwDocAction.BLOCK_UNN))
self.aFmtUnNum.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_UNN)
)
# Format > Separator
self.fmtMenu.addSeparator()
@@ -627,17 +715,23 @@ class GuiMainMenu(QMenuBar):
# Format > Align Left
self.aFmtAlignLeft = self.fmtMenu.addAction(self.tr("Align Left"))
self.aFmtAlignLeft.setShortcut("Ctrl+5")
self.aFmtAlignLeft.triggered.connect(lambda: self._docAction(nwDocAction.ALIGN_L))
self.aFmtAlignLeft.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.ALIGN_L)
)
# Format > Align Centre
self.aFmtAlignCentre = self.fmtMenu.addAction(self.tr("Align Centre"))
self.aFmtAlignCentre.setShortcut("Ctrl+6")
self.aFmtAlignCentre.triggered.connect(lambda: self._docAction(nwDocAction.ALIGN_C))
self.aFmtAlignCentre.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.ALIGN_C)
)
# Format > Align Right
self.aFmtAlignRight = self.fmtMenu.addAction(self.tr("Align Right"))
self.aFmtAlignRight.setShortcut("Ctrl+7")
self.aFmtAlignRight.triggered.connect(lambda: self._docAction(nwDocAction.ALIGN_R))
self.aFmtAlignRight.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.ALIGN_R)
)
# Format > Separator
self.fmtMenu.addSeparator()
@@ -645,12 +739,16 @@ class GuiMainMenu(QMenuBar):
# Format > Indent Left
self.aFmtIndentLeft = self.fmtMenu.addAction(self.tr("Indent Left"))
self.aFmtIndentLeft.setShortcut("Ctrl+8")
self.aFmtIndentLeft.triggered.connect(lambda: self._docAction(nwDocAction.INDENT_L))
self.aFmtIndentLeft.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.INDENT_L)
)
# Format > Indent Right
self.aFmtIndentRight = self.fmtMenu.addAction(self.tr("Indent Right"))
self.aFmtIndentRight.setShortcut("Ctrl+9")
self.aFmtIndentRight.triggered.connect(lambda: self._docAction(nwDocAction.INDENT_R))
self.aFmtIndentRight.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.INDENT_R)
)
# Format > Separator
self.fmtMenu.addSeparator()
@@ -658,27 +756,37 @@ class GuiMainMenu(QMenuBar):
# Format > Comment
self.aFmtComment = self.fmtMenu.addAction(self.tr("Toggle Comment"))
self.aFmtComment.setShortcut("Ctrl+/")
self.aFmtComment.triggered.connect(lambda: self._docAction(nwDocAction.BLOCK_COM))
self.aFmtComment.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_COM)
)
# Format > Remove Block Format
self.aFmtNoFormat = self.fmtMenu.addAction(self.tr("Remove Block Format"))
self.aFmtNoFormat.setShortcuts(["Ctrl+0", "Ctrl+Shift+/"])
self.aFmtNoFormat.triggered.connect(lambda: self._docAction(nwDocAction.BLOCK_TXT))
self.aFmtNoFormat.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_TXT)
)
# Format > Separator
self.fmtMenu.addSeparator()
# Format > Replace Single Quotes
self.aFmtReplSng = self.fmtMenu.addAction(self.tr("Convert Single Quotes"))
self.aFmtReplSng.triggered.connect(lambda: self._docAction(nwDocAction.REPL_SNG))
self.aFmtReplSng.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.REPL_SNG)
)
# Format > Replace Double Quotes
self.aFmtReplDbl = self.fmtMenu.addAction(self.tr("Convert Double Quotes"))
self.aFmtReplDbl.triggered.connect(lambda: self._docAction(nwDocAction.REPL_DBL))
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.triggered.connect(lambda: self._docAction(nwDocAction.RM_BREAKS))
self.aFmtRmBreaks.triggered.connect(
lambda: self.requestDocAction.emit(nwDocAction.RM_BREAKS)
)
return
+30 -15
View File
@@ -62,7 +62,7 @@ from novelwriter.tools.writingstats import GuiWritingStats
from novelwriter.core.coretools import ProjectBuilder
from novelwriter.enum import (
nwDocAction, nwDocMode, nwItemType, nwItemClass, nwWidget, nwView
nwDocAction, nwDocInsert, nwDocMode, nwItemType, nwItemClass, nwWidget, nwView
)
from novelwriter.common import getGuiItem, hexToInt
from novelwriter.constants import nwFiles
@@ -243,6 +243,11 @@ class GuiMain(QMainWindow):
SHARED.projectStatusMessage.connect(self.mainStatus.setStatusMessage)
SHARED.spellLanguageChanged.connect(self.mainStatus.setLanguage)
self.mainMenu.requestDocAction.connect(self._passDocumentAction)
self.mainMenu.requestDocInsert.connect(self._passDocumentInsert)
self.mainMenu.requestDocInsertText.connect(self._passDocumentInsert)
self.mainMenu.requestDocKeyWordInsert.connect(self.docEditor.insertKeyWord)
self.sideBar.viewChangeRequested.connect(self._changeView)
self.projView.selectedItemChanged.connect(self.itemDetails.updateViewBox)
@@ -735,20 +740,6 @@ class GuiMain(QMainWindow):
return True
def passDocumentAction(self, action: nwDocAction) -> None:
"""Pass on document action to the document viewer if it has
focus, or pass it to the document editor if it or any of
its child widgets have focus. If neither has focus, ignore the
action.
"""
if self.docViewer.hasFocus():
self.docViewer.docAction(action)
elif self.docEditor.hasFocus():
self.docEditor.docAction(action)
else:
logger.debug("Action cancelled as neither editor nor viewer has focus")
return
##
# Tree Item Actions
##
@@ -1247,6 +1238,30 @@ class GuiMain(QMainWindow):
return
@pyqtSlot(nwDocAction)
def _passDocumentAction(self, action: nwDocAction) -> None:
"""Pass on a document action to the document viewer if it has
focus, or pass it to the document editor if it or any of its
child widgets have focus. If neither has focus, ignore it.
"""
if self.docViewer.hasFocus():
self.docViewer.docAction(action)
elif self.docEditor.hasFocus():
self.docEditor.docAction(action)
else:
logger.debug("Action cancelled as neither editor nor viewer has focus")
return
@pyqtSlot(str)
@pyqtSlot(nwDocInsert)
def _passDocumentInsert(self, content: str | nwDocInsert) -> None:
"""Pass on a document insert action to the document editor if it
has focus. If not, ignore it.
"""
if self.docEditor.hasFocus():
self.docEditor.insertText(content)
return
@pyqtSlot()
def _timeTick(self) -> None:
"""Process time tick of the main timer."""