Refactor main menu (#2075)
This commit is contained in:
@@ -29,6 +29,7 @@ import unicodedata
|
||||
import uuid
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from collections.abc import Callable
|
||||
from configparser import ConfigParser
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
@@ -414,6 +415,10 @@ def numberToRoman(value: int, toLower: bool = False) -> str:
|
||||
return roman.lower() if toLower else roman
|
||||
|
||||
|
||||
##
|
||||
# Qt Helpers
|
||||
##
|
||||
|
||||
def cssCol(col: QColor, alpha: int | None = None) -> str:
|
||||
"""Convert a QColor object to an rgba entry to use in CSS."""
|
||||
return f"rgba({col.red()}, {col.green()}, {col.blue()}, {alpha or col.alpha()})"
|
||||
@@ -429,6 +434,13 @@ def describeFont(font: QFont) -> str:
|
||||
return "Error"
|
||||
|
||||
|
||||
def qtLambda(func: Callable, *args: Any, **kwargs: Any) -> Callable:
|
||||
"""A replacement for Python lambdas that works for Qt slots."""
|
||||
def wrapper(*args_: Any, **kwargs_: Any) -> None:
|
||||
func(*args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
|
||||
##
|
||||
# Encoder Functions
|
||||
##
|
||||
|
||||
+95
-30
@@ -33,7 +33,7 @@ from PyQt5.QtGui import QDesktopServices
|
||||
from PyQt5.QtWidgets import QAction, QMenuBar
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.common import openExternalPath
|
||||
from novelwriter.common import openExternalPath, qtLambda
|
||||
from novelwriter.constants import nwConst, nwKeyWords, nwLabels, nwStyles, nwUnicode, trConst
|
||||
from novelwriter.enum import nwDocAction, nwDocInsert, nwFocus, nwView
|
||||
from novelwriter.extensions.eventfilters import StatusTipFilter
|
||||
@@ -141,12 +141,13 @@ class GuiMainMenu(QMenuBar):
|
||||
# Project > Save Project
|
||||
self.aSaveProject = self.projMenu.addAction(self.tr("Save Project"))
|
||||
self.aSaveProject.setShortcut("Ctrl+Shift+S")
|
||||
self.aSaveProject.triggered.connect(lambda: self.mainGui.saveProject())
|
||||
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.setShortcut("Ctrl+Shift+W")
|
||||
self.aCloseProject.triggered.connect(lambda: self.mainGui.closeProject(False))
|
||||
self.aCloseProject.triggered.connect(qtLambda(self.mainGui.closeProject, False))
|
||||
|
||||
# Project > Separator
|
||||
self.projMenu.addSeparator()
|
||||
@@ -167,16 +168,17 @@ class GuiMainMenu(QMenuBar):
|
||||
# Project > Edit
|
||||
self.aEditItem = self.projMenu.addAction(self.tr("Rename Item"))
|
||||
self.aEditItem.setShortcut("F2")
|
||||
self.aEditItem.triggered.connect(lambda: self.mainGui.projView.renameTreeItem(None))
|
||||
self.aEditItem.triggered.connect(qtLambda(self.mainGui.projView.renameTreeItem, None))
|
||||
self.mainGui.addAction(self.aEditItem)
|
||||
|
||||
# Project > Delete
|
||||
self.aDeleteItem = self.projMenu.addAction(self.tr("Delete Item"))
|
||||
self.aDeleteItem.setShortcut("Ctrl+Shift+Del") # Cannot be Ctrl+Del, see #629
|
||||
self.aDeleteItem.triggered.connect(lambda: self.mainGui.projView.requestDeleteItem(None))
|
||||
self.aDeleteItem.triggered.connect(qtLambda(self.mainGui.projView.requestDeleteItem, None))
|
||||
|
||||
# Project > Empty Trash
|
||||
self.aEmptyTrash = self.projMenu.addAction(self.tr("Empty Trash"))
|
||||
self.aEmptyTrash.triggered.connect(lambda: self.mainGui.projView.emptyTrash())
|
||||
self.aEmptyTrash.triggered.connect(qtLambda(self.mainGui.projView.emptyTrash))
|
||||
|
||||
# Project > Separator
|
||||
self.projMenu.addSeparator()
|
||||
@@ -185,7 +187,8 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aExitNW = self.projMenu.addAction(self.tr("Exit"))
|
||||
self.aExitNW.setShortcut("Ctrl+Q")
|
||||
self.aExitNW.setMenuRole(QAction.MenuRole.QuitRole)
|
||||
self.aExitNW.triggered.connect(lambda: self.mainGui.closeMain())
|
||||
self.aExitNW.triggered.connect(qtLambda(self.mainGui.closeMain))
|
||||
self.mainGui.addAction(self.aExitNW)
|
||||
|
||||
return
|
||||
|
||||
@@ -203,11 +206,13 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aSaveDoc = self.docuMenu.addAction(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.setShortcut("Ctrl+W")
|
||||
self.aCloseDoc.triggered.connect(self.mainGui.closeDocEditor)
|
||||
self.mainGui.addAction(self.aCloseDoc)
|
||||
|
||||
# Document > Separator
|
||||
self.docuMenu.addSeparator()
|
||||
@@ -215,7 +220,7 @@ class GuiMainMenu(QMenuBar):
|
||||
# Document > Preview
|
||||
self.aViewDoc = self.docuMenu.addAction(self.tr("View Document"))
|
||||
self.aViewDoc.setShortcut("Ctrl+R")
|
||||
self.aViewDoc.triggered.connect(lambda: self.mainGui.viewDocument(None))
|
||||
self.aViewDoc.triggered.connect(qtLambda(self.mainGui.viewDocument, None))
|
||||
|
||||
# Document > Close Preview
|
||||
self.aCloseView = self.docuMenu.addAction(self.tr("Close Document View"))
|
||||
@@ -227,11 +232,11 @@ class GuiMainMenu(QMenuBar):
|
||||
|
||||
# Document > Show File Details
|
||||
self.aFileDetails = self.docuMenu.addAction(self.tr("Show File Details"))
|
||||
self.aFileDetails.triggered.connect(lambda: self.mainGui.docEditor.revealLocation())
|
||||
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.triggered.connect(lambda: self.mainGui.importDocument())
|
||||
self.aImportFile.triggered.connect(qtLambda(self.mainGui.importDocument))
|
||||
|
||||
return
|
||||
|
||||
@@ -246,6 +251,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aEditUndo.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.UNDO)
|
||||
)
|
||||
self.mainGui.addAction(self.aEditUndo)
|
||||
|
||||
# Edit > Redo
|
||||
self.aEditRedo = self.editMenu.addAction(self.tr("Redo"))
|
||||
@@ -253,6 +259,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aEditRedo.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.REDO)
|
||||
)
|
||||
self.mainGui.addAction(self.aEditRedo)
|
||||
|
||||
# Edit > Separator
|
||||
self.editMenu.addSeparator()
|
||||
@@ -263,6 +270,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aEditCut.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.CUT)
|
||||
)
|
||||
self.mainGui.addAction(self.aEditCut)
|
||||
|
||||
# Edit > Copy
|
||||
self.aEditCopy = self.editMenu.addAction(self.tr("Copy"))
|
||||
@@ -270,6 +278,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aEditCopy.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.COPY)
|
||||
)
|
||||
self.mainGui.addAction(self.aEditCopy)
|
||||
|
||||
# Edit > Paste
|
||||
self.aEditPaste = self.editMenu.addAction(self.tr("Paste"))
|
||||
@@ -277,6 +286,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aEditPaste.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.PASTE)
|
||||
)
|
||||
self.mainGui.addAction(self.aEditPaste)
|
||||
|
||||
# Edit > Separator
|
||||
self.editMenu.addSeparator()
|
||||
@@ -287,6 +297,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aSelectAll.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.SEL_ALL)
|
||||
)
|
||||
self.mainGui.addAction(self.aSelectAll)
|
||||
|
||||
# Edit > Select Paragraph
|
||||
self.aSelectPar = self.editMenu.addAction(self.tr("Select Paragraph"))
|
||||
@@ -294,6 +305,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aSelectPar.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.SEL_PARA)
|
||||
)
|
||||
self.mainGui.addAction(self.aSelectPar)
|
||||
|
||||
return
|
||||
|
||||
@@ -343,11 +355,13 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aFocusMode = self.viewMenu.addAction(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.setShortcut("F11")
|
||||
self.aFullScreen.triggered.connect(lambda: self.mainGui.toggleFullScreenMode())
|
||||
self.aFullScreen.triggered.connect(self.mainGui.toggleFullScreenMode)
|
||||
self.mainGui.addAction(self.aFullScreen)
|
||||
|
||||
return
|
||||
|
||||
@@ -365,6 +379,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsENDash.triggered.connect(
|
||||
lambda: self.requestDocInsertText.emit(nwUnicode.U_ENDASH)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsENDash)
|
||||
|
||||
# Insert > Long Dash
|
||||
self.aInsEMDash = self.mInsDashes.addAction(self.tr("Long Dash"))
|
||||
@@ -372,6 +387,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsEMDash.triggered.connect(
|
||||
lambda: self.requestDocInsertText.emit(nwUnicode.U_EMDASH)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsEMDash)
|
||||
|
||||
# Insert > Long Dash
|
||||
self.aInsHorBar = self.mInsDashes.addAction(self.tr("Horizontal Bar"))
|
||||
@@ -379,6 +395,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsHorBar.triggered.connect(
|
||||
lambda: self.requestDocInsertText.emit(nwUnicode.U_HBAR)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsHorBar)
|
||||
|
||||
# Insert > Figure Dash
|
||||
self.aInsFigDash = self.mInsDashes.addAction(self.tr("Figure Dash"))
|
||||
@@ -386,6 +403,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsFigDash.triggered.connect(
|
||||
lambda: self.requestDocInsertText.emit(nwUnicode.U_FGDASH)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsFigDash)
|
||||
|
||||
# Insert > Quote Marks
|
||||
self.mInsQuotes = self.insMenu.addMenu(self.tr("Quote Marks"))
|
||||
@@ -396,6 +414,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsQuoteLS.triggered.connect(
|
||||
lambda: self.requestDocInsert.emit(nwDocInsert.QUOTE_LS)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsQuoteLS)
|
||||
|
||||
# Insert > Right Single Quote
|
||||
self.aInsQuoteRS = self.mInsQuotes.addAction(self.tr("Right Single Quote"))
|
||||
@@ -403,6 +422,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsQuoteRS.triggered.connect(
|
||||
lambda: self.requestDocInsert.emit(nwDocInsert.QUOTE_RS)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsQuoteRS)
|
||||
|
||||
# Insert > Left Double Quote
|
||||
self.aInsQuoteLD = self.mInsQuotes.addAction(self.tr("Left Double Quote"))
|
||||
@@ -410,6 +430,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsQuoteLD.triggered.connect(
|
||||
lambda: self.requestDocInsert.emit(nwDocInsert.QUOTE_LD)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsQuoteLD)
|
||||
|
||||
# Insert > Right Double Quote
|
||||
self.aInsQuoteRD = self.mInsQuotes.addAction(self.tr("Right Double Quote"))
|
||||
@@ -417,6 +438,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsQuoteRD.triggered.connect(
|
||||
lambda: self.requestDocInsert.emit(nwDocInsert.QUOTE_RD)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsQuoteRD)
|
||||
|
||||
# Insert > Alternative Apostrophe
|
||||
self.aInsMSApos = self.mInsQuotes.addAction(self.tr("Alternative Apostrophe"))
|
||||
@@ -424,6 +446,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsMSApos.triggered.connect(
|
||||
lambda: self.requestDocInsertText.emit(nwUnicode.U_MAPOS)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsMSApos)
|
||||
|
||||
# Insert > Symbols
|
||||
self.mInsPunct = self.insMenu.addMenu(self.tr("General Punctuation"))
|
||||
@@ -434,6 +457,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsEllipsis.triggered.connect(
|
||||
lambda: self.requestDocInsertText.emit(nwUnicode.U_HELLIP)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsEllipsis)
|
||||
|
||||
# Insert > Prime
|
||||
self.aInsPrime = self.mInsPunct.addAction(self.tr("Prime"))
|
||||
@@ -441,6 +465,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsPrime.triggered.connect(
|
||||
lambda: self.requestDocInsertText.emit(nwUnicode.U_PRIME)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsPrime)
|
||||
|
||||
# Insert > Double Prime
|
||||
self.aInsDPrime = self.mInsPunct.addAction(self.tr("Double Prime"))
|
||||
@@ -448,6 +473,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsDPrime.triggered.connect(
|
||||
lambda: self.requestDocInsertText.emit(nwUnicode.U_DPRIME)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsDPrime)
|
||||
|
||||
# Insert > White Spaces
|
||||
self.mInsSpace = self.insMenu.addMenu(self.tr("White Spaces"))
|
||||
@@ -458,6 +484,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsNBSpace.triggered.connect(
|
||||
lambda: self.requestDocInsertText.emit(nwUnicode.U_NBSP)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsNBSpace)
|
||||
|
||||
# Insert > Thin Space
|
||||
self.aInsThinSpace = self.mInsSpace.addAction(self.tr("Thin Space"))
|
||||
@@ -465,6 +492,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsThinSpace.triggered.connect(
|
||||
lambda: self.requestDocInsertText.emit(nwUnicode.U_THSP)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsThinSpace)
|
||||
|
||||
# Insert > Thin Non-Breaking Space
|
||||
self.aInsThinNBSpace = self.mInsSpace.addAction(self.tr("Thin Non-Breaking Space"))
|
||||
@@ -472,6 +500,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsThinNBSpace.triggered.connect(
|
||||
lambda: self.requestDocInsertText.emit(nwUnicode.U_THNBSP)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsThinNBSpace)
|
||||
|
||||
# Insert > Symbols
|
||||
self.mInsSymbol = self.insMenu.addMenu(self.tr("Other Symbols"))
|
||||
@@ -482,6 +511,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsBullet.triggered.connect(
|
||||
lambda: self.requestDocInsertText.emit(nwUnicode.U_BULL)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsBullet)
|
||||
|
||||
# Insert > Hyphen Bullet
|
||||
self.aInsHyBull = self.mInsSymbol.addAction(self.tr("Hyphen Bullet"))
|
||||
@@ -489,6 +519,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsHyBull.triggered.connect(
|
||||
lambda: self.requestDocInsertText.emit(nwUnicode.U_HYBULL)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsHyBull)
|
||||
|
||||
# Insert > Flower Mark
|
||||
self.aInsFlower = self.mInsSymbol.addAction(self.tr("Flower Mark"))
|
||||
@@ -496,6 +527,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsFlower.triggered.connect(
|
||||
lambda: self.requestDocInsertText.emit(nwUnicode.U_FLOWER)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsFlower)
|
||||
|
||||
# Insert > Per Mille
|
||||
self.aInsPerMille = self.mInsSymbol.addAction(self.tr("Per Mille"))
|
||||
@@ -503,6 +535,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsPerMille.triggered.connect(
|
||||
lambda: self.requestDocInsertText.emit(nwUnicode.U_PERMIL)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsPerMille)
|
||||
|
||||
# Insert > Degree Symbol
|
||||
self.aInsDegree = self.mInsSymbol.addAction(self.tr("Degree Symbol"))
|
||||
@@ -510,6 +543,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsDegree.triggered.connect(
|
||||
lambda: self.requestDocInsertText.emit(nwUnicode.U_DEGREE)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsDegree)
|
||||
|
||||
# Insert > Minus Sign
|
||||
self.aInsMinus = self.mInsSymbol.addAction(self.tr("Minus Sign"))
|
||||
@@ -517,6 +551,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsMinus.triggered.connect(
|
||||
lambda: self.requestDocInsertText.emit(nwUnicode.U_MINUS)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsMinus)
|
||||
|
||||
# Insert > Times Sign
|
||||
self.aInsTimes = self.mInsSymbol.addAction(self.tr("Times Sign"))
|
||||
@@ -524,6 +559,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsTimes.triggered.connect(
|
||||
lambda: self.requestDocInsertText.emit(nwUnicode.U_TIMES)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsTimes)
|
||||
|
||||
# Insert > Division
|
||||
self.aInsDivide = self.mInsSymbol.addAction(self.tr("Division Sign"))
|
||||
@@ -531,6 +567,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsDivide.triggered.connect(
|
||||
lambda: self.requestDocInsertText.emit(nwUnicode.U_DIVIDE)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsDivide)
|
||||
|
||||
# Insert > Tags and References
|
||||
self.mInsKeywords = self.insMenu.addMenu(self.tr("Tags and References"))
|
||||
@@ -546,13 +583,13 @@ class GuiMainMenu(QMenuBar):
|
||||
self.mInsKWItems[nwKeyWords.ENTITY_KEY] = (QAction(self.mInsKeywords), "Ctrl+K, E")
|
||||
self.mInsKWItems[nwKeyWords.CUSTOM_KEY] = (QAction(self.mInsKeywords), "Ctrl+K, X")
|
||||
self.mInsKWItems[nwKeyWords.MENTION_KEY] = (QAction(self.mInsKeywords), "Ctrl+K, M")
|
||||
for n, keyWord in enumerate(self.mInsKWItems):
|
||||
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.requestDocKeyWordInsert.emit(keyWord)
|
||||
)
|
||||
self.mInsKeywords.addAction(self.mInsKWItems[keyWord][0])
|
||||
for key in self.mInsKWItems:
|
||||
action = self.mInsKWItems[key][0]
|
||||
action.setText(trConst(nwLabels.KEY_NAME[key]))
|
||||
action.setShortcut(self.mInsKWItems[key][1])
|
||||
action.triggered.connect(qtLambda(self.requestDocKeyWordInsert.emit, key))
|
||||
self.mInsKeywords.addAction(action)
|
||||
self.mainGui.addAction(self.mInsKWItems[key][0])
|
||||
|
||||
# Insert > Special Comments
|
||||
self.mInsComments = self.insMenu.addMenu(self.tr("Special Comments"))
|
||||
@@ -563,6 +600,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsSynopsis.triggered.connect(
|
||||
lambda: self.requestDocInsert.emit(nwDocInsert.SYNOPSIS)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsSynopsis)
|
||||
|
||||
# Insert > Short Description Comment
|
||||
self.aInsShort = self.mInsComments.addAction(self.tr("Short Description Comment"))
|
||||
@@ -570,6 +608,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aInsShort.triggered.connect(
|
||||
lambda: self.requestDocInsert.emit(nwDocInsert.SHORT)
|
||||
)
|
||||
self.mainGui.addAction(self.aInsShort)
|
||||
|
||||
# Insert > Breaks and Vertical Space
|
||||
self.mInsBreaks = self.insMenu.addMenu(self.tr("Breaks and Vertical Space"))
|
||||
@@ -623,6 +662,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aFmtBold.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.MD_BOLD)
|
||||
)
|
||||
self.mainGui.addAction(self.aFmtBold)
|
||||
|
||||
# Format > Italic
|
||||
self.aFmtItalic = self.fmtMenu.addAction(self.tr("Italic"))
|
||||
@@ -630,6 +670,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aFmtItalic.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.MD_ITALIC)
|
||||
)
|
||||
self.mainGui.addAction(self.aFmtItalic)
|
||||
|
||||
# Format > Strikethrough
|
||||
self.aFmtStrike = self.fmtMenu.addAction(self.tr("Strikethrough"))
|
||||
@@ -637,6 +678,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aFmtStrike.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.MD_STRIKE)
|
||||
)
|
||||
self.mainGui.addAction(self.aFmtStrike)
|
||||
|
||||
# Edit > Separator
|
||||
self.fmtMenu.addSeparator()
|
||||
@@ -647,6 +689,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aFmtDQuote.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.D_QUOTE)
|
||||
)
|
||||
self.mainGui.addAction(self.aFmtDQuote)
|
||||
|
||||
# Format > Single Quotes
|
||||
self.aFmtSQuote = self.fmtMenu.addAction(self.tr("Wrap Single Quotes"))
|
||||
@@ -654,6 +697,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aFmtSQuote.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.S_QUOTE)
|
||||
)
|
||||
self.mainGui.addAction(self.aFmtSQuote)
|
||||
|
||||
# Format > Separator
|
||||
self.fmtMenu.addSeparator()
|
||||
@@ -712,6 +756,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aFmtHead1.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H1)
|
||||
)
|
||||
self.mainGui.addAction(self.aFmtHead1)
|
||||
|
||||
# Format > Heading 2 (Chapter)
|
||||
self.aFmtHead2 = self.fmtMenu.addAction(trConst(nwStyles.T_LABEL["H2"]))
|
||||
@@ -719,6 +764,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aFmtHead2.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H2)
|
||||
)
|
||||
self.mainGui.addAction(self.aFmtHead2)
|
||||
|
||||
# Format > Heading 3 (Scene)
|
||||
self.aFmtHead3 = self.fmtMenu.addAction(trConst(nwStyles.T_LABEL["H3"]))
|
||||
@@ -726,6 +772,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aFmtHead3.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H3)
|
||||
)
|
||||
self.mainGui.addAction(self.aFmtHead3)
|
||||
|
||||
# Format > Heading 4 (Section)
|
||||
self.aFmtHead4 = self.fmtMenu.addAction(trConst(nwStyles.T_LABEL["H4"]))
|
||||
@@ -733,6 +780,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aFmtHead4.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H4)
|
||||
)
|
||||
self.mainGui.addAction(self.aFmtHead4)
|
||||
|
||||
# Format > Separator
|
||||
self.fmtMenu.addSeparator()
|
||||
@@ -764,6 +812,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aFmtAlignLeft.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.ALIGN_L)
|
||||
)
|
||||
self.mainGui.addAction(self.aFmtAlignLeft)
|
||||
|
||||
# Format > Align Centre
|
||||
self.aFmtAlignCentre = self.fmtMenu.addAction(self.tr("Align Centre"))
|
||||
@@ -771,6 +820,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aFmtAlignCentre.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.ALIGN_C)
|
||||
)
|
||||
self.mainGui.addAction(self.aFmtAlignCentre)
|
||||
|
||||
# Format > Align Right
|
||||
self.aFmtAlignRight = self.fmtMenu.addAction(self.tr("Align Right"))
|
||||
@@ -778,6 +828,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aFmtAlignRight.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.ALIGN_R)
|
||||
)
|
||||
self.mainGui.addAction(self.aFmtAlignRight)
|
||||
|
||||
# Format > Separator
|
||||
self.fmtMenu.addSeparator()
|
||||
@@ -788,6 +839,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aFmtIndentLeft.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.INDENT_L)
|
||||
)
|
||||
self.mainGui.addAction(self.aFmtIndentLeft)
|
||||
|
||||
# Format > Indent Right
|
||||
self.aFmtIndentRight = self.fmtMenu.addAction(self.tr("Indent Right"))
|
||||
@@ -795,6 +847,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aFmtIndentRight.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.INDENT_R)
|
||||
)
|
||||
self.mainGui.addAction(self.aFmtIndentRight)
|
||||
|
||||
# Format > Separator
|
||||
self.fmtMenu.addSeparator()
|
||||
@@ -805,6 +858,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aFmtComment.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_COM)
|
||||
)
|
||||
self.mainGui.addAction(self.aFmtComment)
|
||||
|
||||
# Format > Ignore Text
|
||||
self.aFmtIgnore = self.fmtMenu.addAction(self.tr("Toggle Ignore Text"))
|
||||
@@ -819,6 +873,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aFmtNoFormat.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_TXT)
|
||||
)
|
||||
self.mainGui.addAction(self.aFmtNoFormat)
|
||||
|
||||
# Format > Separator
|
||||
self.fmtMenu.addSeparator()
|
||||
@@ -851,29 +906,34 @@ class GuiMainMenu(QMenuBar):
|
||||
# Search > Find
|
||||
self.aFind = self.srcMenu.addAction(self.tr("Find"))
|
||||
self.aFind.setShortcut("Ctrl+F")
|
||||
self.aFind.triggered.connect(lambda: self.mainGui.docEditor.beginSearch())
|
||||
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.setShortcut("Ctrl+=" if CONFIG.osDarwin else "Ctrl+H")
|
||||
self.aReplace.triggered.connect(lambda: self.mainGui.docEditor.beginReplace())
|
||||
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.setShortcuts(["Ctrl+G", "F3"] if CONFIG.osDarwin else ["F3", "Ctrl+G"])
|
||||
self.aFindNext.triggered.connect(lambda: self.mainGui.docEditor.findNext())
|
||||
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.setShortcuts(
|
||||
["Ctrl+Shift+G", "Shift+F3"] if CONFIG.osDarwin else ["Shift+F3", "Ctrl+Shift+G"]
|
||||
)
|
||||
self.aFindPrev.triggered.connect(lambda: self.mainGui.docEditor.findNext(goBack=True))
|
||||
self.aFindPrev.triggered.connect(qtLambda(self.mainGui.docEditor.findNext, goBack=True))
|
||||
self.mainGui.addAction(self.aFindPrev)
|
||||
|
||||
# Search > Replace Next
|
||||
self.aReplaceNext = self.srcMenu.addAction(self.tr("Replace Next"))
|
||||
self.aReplaceNext.setShortcut("Ctrl+Shift+1")
|
||||
self.aReplaceNext.triggered.connect(lambda: self.mainGui.docEditor.replaceNext())
|
||||
self.aReplaceNext.triggered.connect(qtLambda(self.mainGui.docEditor.replaceNext))
|
||||
self.mainGui.addAction(self.aReplaceNext)
|
||||
|
||||
# Search > Separator
|
||||
self.srcMenu.addSeparator()
|
||||
@@ -896,6 +956,7 @@ class GuiMainMenu(QMenuBar):
|
||||
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"))
|
||||
languages = SHARED.spelling.listDictionaries()
|
||||
@@ -909,7 +970,8 @@ class GuiMainMenu(QMenuBar):
|
||||
# Tools > Re-Run Spell Check
|
||||
self.aReRunSpell = self.toolsMenu.addAction(self.tr("Re-Run Spell Check"))
|
||||
self.aReRunSpell.setShortcut("F7")
|
||||
self.aReRunSpell.triggered.connect(lambda: self.mainGui.docEditor.spellCheckDocument())
|
||||
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"))
|
||||
@@ -926,14 +988,14 @@ class GuiMainMenu(QMenuBar):
|
||||
# Tools > Rebuild Index
|
||||
self.aRebuildIndex = self.toolsMenu.addAction(self.tr("Rebuild Index"))
|
||||
self.aRebuildIndex.setShortcut("F9")
|
||||
self.aRebuildIndex.triggered.connect(lambda: self.mainGui.rebuildIndex())
|
||||
self.aRebuildIndex.triggered.connect(qtLambda(self.mainGui.rebuildIndex))
|
||||
|
||||
# Tools > Separator
|
||||
self.toolsMenu.addSeparator()
|
||||
|
||||
# Tools > Backup Project
|
||||
self.aBackupProject = self.toolsMenu.addAction(self.tr("Backup Project"))
|
||||
self.aBackupProject.triggered.connect(lambda: SHARED.project.backupProject(True))
|
||||
self.aBackupProject.triggered.connect(qtLambda(SHARED.project.backupProject, True))
|
||||
|
||||
# Tools > Build Manuscript
|
||||
self.aBuildManuscript = self.toolsMenu.addAction(self.tr("Build Manuscript"))
|
||||
@@ -950,6 +1012,7 @@ class GuiMainMenu(QMenuBar):
|
||||
self.aPreferences.setShortcut("Ctrl+,")
|
||||
self.aPreferences.setMenuRole(QAction.MenuRole.PreferencesRole)
|
||||
self.aPreferences.triggered.connect(self.mainGui.showPreferencesDialog)
|
||||
self.mainGui.addAction(self.aPreferences)
|
||||
|
||||
return
|
||||
|
||||
@@ -974,27 +1037,29 @@ class GuiMainMenu(QMenuBar):
|
||||
# Help > User Manual (Online)
|
||||
self.aHelpDocs = self.helpMenu.addAction(self.tr("User Manual (Online)"))
|
||||
self.aHelpDocs.setShortcut("F1")
|
||||
self.aHelpDocs.triggered.connect(lambda: self._openWebsite(nwConst.URL_DOCS))
|
||||
self.aHelpDocs.triggered.connect(qtLambda(self._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.setShortcut("Shift+F1")
|
||||
self.aPdfDocs.triggered.connect(self._openUserManualFile)
|
||||
self.mainGui.addAction(self.aPdfDocs)
|
||||
|
||||
# Help > Separator
|
||||
self.helpMenu.addSeparator()
|
||||
|
||||
# Document > Report an Issue
|
||||
self.aIssue = self.helpMenu.addAction(self.tr("Report an Issue (GitHub)"))
|
||||
self.aIssue.triggered.connect(lambda: self._openWebsite(nwConst.URL_REPORT))
|
||||
self.aIssue.triggered.connect(qtLambda(self._openWebsite, nwConst.URL_REPORT))
|
||||
|
||||
# Document > Ask a Question
|
||||
self.aQuestion = self.helpMenu.addAction(self.tr("Ask a Question (GitHub)"))
|
||||
self.aQuestion.triggered.connect(lambda: self._openWebsite(nwConst.URL_HELP))
|
||||
self.aQuestion.triggered.connect(qtLambda(self._openWebsite, nwConst.URL_HELP))
|
||||
|
||||
# Document > Main Website
|
||||
self.aWebsite = self.helpMenu.addAction(self.tr("The novelWriter Website"))
|
||||
self.aWebsite.triggered.connect(lambda: self._openWebsite(nwConst.URL_WEB))
|
||||
self.aWebsite.triggered.connect(qtLambda(self._openWebsite, nwConst.URL_WEB))
|
||||
|
||||
return
|
||||
|
||||
+7
-101
@@ -289,9 +289,7 @@ class GuiMain(QMainWindow):
|
||||
self.asDocTimer = QTimer(self)
|
||||
self.asDocTimer.timeout.connect(self._autoSaveDocument)
|
||||
|
||||
# Shortcuts and Actions
|
||||
self._connectMenuActions()
|
||||
|
||||
# Shortcuts
|
||||
self.keyReturn = QShortcut(self)
|
||||
self.keyReturn.setKey("Return")
|
||||
self.keyReturn.activated.connect(self._keyPressReturn)
|
||||
@@ -906,11 +904,6 @@ class GuiMain(QMainWindow):
|
||||
|
||||
return not self.splitView.isVisible()
|
||||
|
||||
def toggleFullScreenMode(self) -> None:
|
||||
"""Toggle full screen mode"""
|
||||
self.setWindowState(self.windowState() ^ Qt.WindowState.WindowFullScreen)
|
||||
return
|
||||
|
||||
##
|
||||
# Events
|
||||
##
|
||||
@@ -926,6 +919,12 @@ class GuiMain(QMainWindow):
|
||||
# Public Slots
|
||||
##
|
||||
|
||||
@pyqtSlot()
|
||||
def toggleFullScreenMode(self) -> None:
|
||||
"""Toggle full screen mode"""
|
||||
self.setWindowState(self.windowState() ^ Qt.WindowState.WindowFullScreen)
|
||||
return
|
||||
|
||||
@pyqtSlot()
|
||||
def closeDocEditor(self) -> None:
|
||||
"""Close the document editor. This does not hide the editor."""
|
||||
@@ -1299,99 +1298,6 @@ class GuiMain(QMainWindow):
|
||||
# Internal Functions
|
||||
##
|
||||
|
||||
def _connectMenuActions(self) -> None:
|
||||
"""Connect to the main window all menu actions that need to be
|
||||
available also when the main menu is hidden.
|
||||
"""
|
||||
# Project
|
||||
self.addAction(self.mainMenu.aSaveProject)
|
||||
self.addAction(self.mainMenu.aEditItem)
|
||||
self.addAction(self.mainMenu.aExitNW)
|
||||
|
||||
# Document
|
||||
self.addAction(self.mainMenu.aSaveDoc)
|
||||
self.addAction(self.mainMenu.aCloseDoc)
|
||||
|
||||
# Edit
|
||||
self.addAction(self.mainMenu.aEditUndo)
|
||||
self.addAction(self.mainMenu.aEditRedo)
|
||||
self.addAction(self.mainMenu.aEditCut)
|
||||
self.addAction(self.mainMenu.aEditCopy)
|
||||
self.addAction(self.mainMenu.aEditPaste)
|
||||
self.addAction(self.mainMenu.aSelectAll)
|
||||
self.addAction(self.mainMenu.aSelectPar)
|
||||
|
||||
# View
|
||||
self.addAction(self.mainMenu.aFocusMode)
|
||||
self.addAction(self.mainMenu.aFullScreen)
|
||||
|
||||
# Insert
|
||||
self.addAction(self.mainMenu.aInsENDash)
|
||||
self.addAction(self.mainMenu.aInsEMDash)
|
||||
self.addAction(self.mainMenu.aInsHorBar)
|
||||
self.addAction(self.mainMenu.aInsFigDash)
|
||||
self.addAction(self.mainMenu.aInsQuoteLS)
|
||||
self.addAction(self.mainMenu.aInsQuoteRS)
|
||||
self.addAction(self.mainMenu.aInsQuoteLD)
|
||||
self.addAction(self.mainMenu.aInsQuoteRD)
|
||||
self.addAction(self.mainMenu.aInsMSApos)
|
||||
self.addAction(self.mainMenu.aInsEllipsis)
|
||||
self.addAction(self.mainMenu.aInsPrime)
|
||||
self.addAction(self.mainMenu.aInsDPrime)
|
||||
self.addAction(self.mainMenu.aInsNBSpace)
|
||||
self.addAction(self.mainMenu.aInsThinSpace)
|
||||
self.addAction(self.mainMenu.aInsThinNBSpace)
|
||||
self.addAction(self.mainMenu.aInsBullet)
|
||||
self.addAction(self.mainMenu.aInsHyBull)
|
||||
self.addAction(self.mainMenu.aInsFlower)
|
||||
self.addAction(self.mainMenu.aInsPerMille)
|
||||
self.addAction(self.mainMenu.aInsDegree)
|
||||
self.addAction(self.mainMenu.aInsMinus)
|
||||
self.addAction(self.mainMenu.aInsTimes)
|
||||
self.addAction(self.mainMenu.aInsDivide)
|
||||
self.addAction(self.mainMenu.aInsSynopsis)
|
||||
self.addAction(self.mainMenu.aInsShort)
|
||||
|
||||
for mAction, _ in self.mainMenu.mInsKWItems.values():
|
||||
self.addAction(mAction)
|
||||
|
||||
# Search
|
||||
self.addAction(self.mainMenu.aFind)
|
||||
self.addAction(self.mainMenu.aReplace)
|
||||
self.addAction(self.mainMenu.aFindNext)
|
||||
self.addAction(self.mainMenu.aFindPrev)
|
||||
self.addAction(self.mainMenu.aReplaceNext)
|
||||
|
||||
# Format
|
||||
self.addAction(self.mainMenu.aFmtItalic)
|
||||
self.addAction(self.mainMenu.aFmtBold)
|
||||
self.addAction(self.mainMenu.aFmtStrike)
|
||||
self.addAction(self.mainMenu.aFmtDQuote)
|
||||
self.addAction(self.mainMenu.aFmtSQuote)
|
||||
self.addAction(self.mainMenu.aFmtHead1)
|
||||
self.addAction(self.mainMenu.aFmtHead2)
|
||||
self.addAction(self.mainMenu.aFmtHead3)
|
||||
self.addAction(self.mainMenu.aFmtHead4)
|
||||
self.addAction(self.mainMenu.aFmtAlignLeft)
|
||||
self.addAction(self.mainMenu.aFmtAlignCentre)
|
||||
self.addAction(self.mainMenu.aFmtAlignRight)
|
||||
self.addAction(self.mainMenu.aFmtIndentLeft)
|
||||
self.addAction(self.mainMenu.aFmtIndentRight)
|
||||
self.addAction(self.mainMenu.aFmtComment)
|
||||
self.addAction(self.mainMenu.aFmtNoFormat)
|
||||
|
||||
# Tools
|
||||
self.addAction(self.mainMenu.aSpellCheck)
|
||||
self.addAction(self.mainMenu.aReRunSpell)
|
||||
self.addAction(self.mainMenu.aPreferences)
|
||||
|
||||
# Help
|
||||
self.addAction(self.mainMenu.aHelpDocs)
|
||||
if isinstance(CONFIG.pdfDocs, Path):
|
||||
self.addAction(self.mainMenu.aPdfDocs)
|
||||
|
||||
return
|
||||
|
||||
def _updateWindowTitle(self, projName: str | None = None) -> None:
|
||||
"""Set the window title and add the project's name."""
|
||||
self.setWindowTitle(" - ".join(filter(None, [projName, CONFIG.appName])))
|
||||
|
||||
Reference in New Issue
Block a user