Editor code cleanup, and a few other places (#2201)

This commit is contained in:
Veronica Berglyd Olsen
2025-01-22 00:46:51 +01:00
committed by GitHub
24 changed files with 166 additions and 189 deletions
-1
View File
@@ -178,7 +178,6 @@ SETTINGS_LABELS = {
}
RENAMED = {
"odt.addColours": "doc.addColours",
"odt.pageHeader": "doc.pageHeader",
"odt.pageCountOffset": "doc.pageCountOffset",
}
+2 -2
View File
@@ -32,7 +32,7 @@ from PyQt6.QtWidgets import (
from novelwriter import CONFIG, SHARED
from novelwriter.common import cssCol, readTextFile
from novelwriter.extensions.configlayout import NColourLabel
from novelwriter.extensions.configlayout import NColorLabel
from novelwriter.extensions.modified import NDialog
from novelwriter.extensions.versioninfo import VersionInfoWidget
from novelwriter.types import QtAlignRightTop, QtDialogClose
@@ -68,7 +68,7 @@ class GuiAbout(NDialog):
self.nwLicence.setOpenExternalLinks(True)
# Credits
self.lblCredits = NColourLabel(
self.lblCredits = NColorLabel(
self.tr("Credits"), self, scale=1.6, bold=True
)
+2 -2
View File
@@ -33,7 +33,7 @@ from PyQt6.QtWidgets import (
)
from novelwriter import SHARED
from novelwriter.extensions.configlayout import NColourLabel
from novelwriter.extensions.configlayout import NColorLabel
from novelwriter.extensions.modified import NDialog
from novelwriter.extensions.switch import NSwitch
from novelwriter.types import QtAccepted, QtDialogCancel, QtDialogOk, QtDialogReset, QtUserRole
@@ -56,7 +56,7 @@ class GuiDocMerge(NDialog):
self.headLabel = QLabel(self.tr("Documents to Merge"), self)
self.headLabel.setFont(SHARED.theme.guiFontB)
self.helpLabel = NColourLabel(
self.helpLabel = NColorLabel(
self.tr("Drag and drop items to change the order, or uncheck to exclude."),
self, color=SHARED.theme.helpText, wrap=True
)
+2 -2
View File
@@ -33,7 +33,7 @@ from PyQt6.QtWidgets import (
)
from novelwriter import SHARED
from novelwriter.extensions.configlayout import NColourLabel
from novelwriter.extensions.configlayout import NColorLabel
from novelwriter.extensions.modified import NDialog
from novelwriter.extensions.switch import NSwitch
from novelwriter.types import QtAccepted, QtDialogCancel, QtDialogOk, QtUserRole
@@ -60,7 +60,7 @@ class GuiDocSplit(NDialog):
self.headLabel = QLabel(self.tr("Document Headings"), self)
self.headLabel.setFont(SHARED.theme.guiFontB)
self.helpLabel = NColourLabel(
self.helpLabel = NColorLabel(
self.tr("Select the maximum level to split into files."),
self, color=SHARED.theme.helpText, wrap=True
)
+3 -3
View File
@@ -38,7 +38,7 @@ from novelwriter.common import compact, describeFont, uniqueCompact
from novelwriter.config import DEF_GUI, DEF_ICONS, DEF_SYNTAX, DEF_TREECOL
from novelwriter.constants import nwLabels, nwUnicode, trConst
from novelwriter.dialogs.quotes import GuiQuoteSelect
from novelwriter.extensions.configlayout import NColourLabel, NScrollableForm
from novelwriter.extensions.configlayout import NColorLabel, NScrollableForm
from novelwriter.extensions.modified import (
NComboBox, NDialog, NDoubleSpinBox, NIconToolButton, NSpinBox
)
@@ -63,9 +63,9 @@ class GuiPreferences(NDialog):
self.resize(*CONFIG.prefsWinSize)
# Title
self.titleLabel = NColourLabel(
self.titleLabel = NColorLabel(
self.tr("Preferences"), self, color=SHARED.theme.helpText,
scale=NColourLabel.HEADER_SCALE, indent=4,
scale=NColorLabel.HEADER_SCALE, indent=4,
)
# Search Box
+9 -9
View File
@@ -42,7 +42,7 @@ from novelwriter.common import formatFileFilter, qtLambda, simplified
from novelwriter.constants import nwLabels, trConst
from novelwriter.core.status import NWStatus, StatusEntry
from novelwriter.enum import nwStatusShape
from novelwriter.extensions.configlayout import NColourLabel, NFixedPage, NScrollableForm
from novelwriter.extensions.configlayout import NColorLabel, NFixedPage, NScrollableForm
from novelwriter.extensions.modified import NComboBox, NDialog, NIconToolButton
from novelwriter.extensions.pagedsidebar import NPagedSideBar
from novelwriter.extensions.switch import NSwitch
@@ -78,9 +78,9 @@ class GuiProjectSettings(NDialog):
)
# Title
self.titleLabel = NColourLabel(
self.titleLabel = NColorLabel(
self.tr("Project Settings"), self, color=SHARED.theme.helpText,
scale=NColourLabel.HEADER_SCALE, indent=4,
scale=NColorLabel.HEADER_SCALE, indent=4,
)
# SideBar
@@ -339,9 +339,9 @@ class _StatusPage(NFixedPage):
self.trSelColor = self.tr("Select Colour")
# Title
self.pageTitle = NColourLabel(
self.pageTitle = NColorLabel(
pageLabel, self, color=SHARED.theme.helpText,
scale=NColourLabel.HEADER_SCALE
scale=NColorLabel.HEADER_SCALE
)
# List Box
@@ -398,7 +398,7 @@ class _StatusPage(NFixedPage):
self.colorButton.setSizePolicy(QtSizeMinimum, QtSizeMinimumExpanding)
self.colorButton.setStyleSheet(buttonStyle)
self.colorButton.setEnabled(False)
self.colorButton.clicked.connect(self._onColourSelect)
self.colorButton.clicked.connect(self._onColorSelect)
def buildMenu(menu: QMenu | None, items: dict[nwStatusShape, str]) -> None:
if menu is not None:
@@ -494,7 +494,7 @@ class _StatusPage(NFixedPage):
return
@pyqtSlot()
def _onColourSelect(self) -> None:
def _onColorSelect(self) -> None:
"""Open a dialog to select the status icon colour."""
if (color := QColorDialog.getColor(self._color, self, self.trSelColor)).isValid():
self._color = color
@@ -675,9 +675,9 @@ class _ReplacePage(NFixedPage):
wCol0 = SHARED.project.options.getInt("GuiProjectSettings", "replaceColW", 130)
# Title
self.pageTitle = NColourLabel(
self.pageTitle = NColorLabel(
self.tr("Text Auto-Replace for Preview and Build"), self,
color=SHARED.theme.helpText, scale=NColourLabel.HEADER_SCALE
color=SHARED.theme.helpText, scale=NColorLabel.HEADER_SCALE
)
# List Box
+3 -3
View File
@@ -37,7 +37,7 @@ from PyQt6.QtWidgets import (
from novelwriter import CONFIG, SHARED
from novelwriter.common import formatFileFilter
from novelwriter.core.spellcheck import UserDictionary
from novelwriter.extensions.configlayout import NColourLabel
from novelwriter.extensions.configlayout import NColorLabel
from novelwriter.extensions.modified import NDialog, NIconToolButton
from novelwriter.types import QtDialogClose, QtDialogSave
@@ -65,9 +65,9 @@ class GuiWordList(NDialog):
)
# Header
self.headLabel = NColourLabel(
self.headLabel = NColorLabel(
self.tr("Project Word List"), self, color=SHARED.theme.helpText,
scale=NColourLabel.HEADER_SCALE
scale=NColorLabel.HEADER_SCALE
)
self.importButton = NIconToolButton(self, iSz, "import", "green")
+3 -3
View File
@@ -101,7 +101,7 @@ class NScrollableForm(QScrollArea):
self._indent = 12
self._sections: dict[int, QLabel] = {}
self._editable: dict[str, NColourLabel] = {}
self._editable: dict[str, NColorLabel] = {}
self._index: dict[str, QWidget] = {}
self._layout = QVBoxLayout()
@@ -216,7 +216,7 @@ class NScrollableForm(QScrollArea):
qLabel.setBuddy(qWidget)
if helpText:
qHelp = NColourLabel(
qHelp = NColorLabel(
str(helpText), self, color=self._helpCol,
scale=self._fontScale, wrap=True, indent=self._indent
)
@@ -257,7 +257,7 @@ class NScrollableForm(QScrollArea):
return
class NColourLabel(QLabel):
class NColorLabel(QLabel):
"""Extension: A Coloured Label
A custom widget that draws a label in a specific colour, and
+5 -3
View File
@@ -56,7 +56,7 @@ class NProgressCircle(QProgressBar):
self._cRect = QRect(point, point, size - 2*point, size - 2*point)
self._dPen = QPen(QtTransparent)
self._dBrush = QBrush(QtTransparent)
self.setColours(
self.setColors(
track=self.palette().alternateBase().color(),
bar=self.palette().highlight().color(),
text=self.palette().text().color()
@@ -66,8 +66,10 @@ class NProgressCircle(QProgressBar):
self.setFixedHeight(size)
return
def setColours(self, back: QColor | None = None, track: QColor | None = None,
bar: QColor | None = None, text: QColor | None = None) -> None:
def setColors(
self, back: QColor | None = None, track: QColor | None = None,
bar: QColor | None = None, text: QColor | None = None
) -> None:
"""Set the colours of the widget."""
if isinstance(back, QColor):
self._dPen = QPen(back)
+55 -85
View File
@@ -61,7 +61,7 @@ from novelwriter.enum import (
nwChange, nwComment, nwDocAction, nwDocInsert, nwDocMode, nwItemClass,
nwItemType, nwTrinary
)
from novelwriter.extensions.configlayout import NColourLabel
from novelwriter.extensions.configlayout import NColorLabel
from novelwriter.extensions.eventfilters import WheelEventFilter
from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton
from novelwriter.gui.dochighlight import BLOCK_META, BLOCK_TITLE
@@ -219,7 +219,7 @@ class GuiDocEditor(QPlainTextEdit):
self.changeFocusState = self.docHeader.changeFocusState
# Finalise
self.updateSyntaxColours()
self.updateSyntaxColors()
self.initEditor()
logger.debug("Ready: GuiDocEditor")
@@ -287,7 +287,7 @@ class GuiDocEditor(QPlainTextEdit):
self.docToolBar.updateTheme()
return
def updateSyntaxColours(self) -> None:
def updateSyntaxColors(self) -> None:
"""Update the syntax highlighting theme."""
syntax = SHARED.theme.syntaxTheme
@@ -303,8 +303,8 @@ class GuiDocEditor(QPlainTextEdit):
palette.setColor(QPalette.ColorRole.Text, syntax.text)
viewport.setPalette(palette)
self.docHeader.matchColours()
self.docFooter.matchColours()
self.docHeader.matchColors()
self.docFooter.matchColors()
return
@@ -339,14 +339,12 @@ class GuiDocEditor(QPlainTextEdit):
# Also set the document text options for the document text flow
options = QTextOption()
if CONFIG.doJustify:
options.setAlignment(QtAlignJustify)
if CONFIG.showTabsNSpaces:
options.setFlags(options.flags() | QTextOption.Flag.ShowTabsAndSpaces)
if CONFIG.showLineEndings:
options.setFlags(options.flags() | QTextOption.Flag.ShowLineAndParagraphSeparators)
self._qDocument.setDefaultTextOption(options)
# Scrolling
@@ -379,19 +377,19 @@ class GuiDocEditor(QPlainTextEdit):
"""Load text from a document into the editor. If we have an I/O
error, we must handle this and clear the editor so that we don't
risk overwriting the file if it exists. This can for instance
happen of the file contains binary elements or an encoding that
happen if the file contains binary elements or an encoding that
novelWriter does not support. If loading is successful, or the
document is new (empty string), we set up the editor for editing
the file.
"""
self._nwDocument = SHARED.project.storage.getDocument(tHandle)
self._nwItem = self._nwDocument.nwItem
if not ((nwItem := self._nwItem) and nwItem.itemType == nwItemType.FILE):
if not (self._nwItem and self._nwItem.itemType == nwItemType.FILE):
logger.debug("Requested item '%s' is not a document", tHandle)
self.clearEditor()
return False
if (docText := self._nwDocument.readDocument()) is None:
if (text := self._nwDocument.readDocument()) is None:
# There was an I/O error
self.clearEditor()
return False
@@ -400,7 +398,7 @@ class GuiDocEditor(QPlainTextEdit):
self._docHandle = tHandle
self._allowAutoReplace(False)
self._qDocument.setTextContent(docText, tHandle)
self._qDocument.setTextContent(text, tHandle)
self._allowAutoReplace(True)
QApplication.processEvents()
@@ -415,7 +413,7 @@ class GuiDocEditor(QPlainTextEdit):
if isinstance(tLine, int):
self.setCursorLine(tLine)
else:
self.setCursorPosition(nwItem.cursorPos)
self.setCursorPosition(self._nwItem.cursorPos)
self.docHeader.setHandle(tHandle)
self.docFooter.setHandle(tHandle)
@@ -438,7 +436,7 @@ class GuiDocEditor(QPlainTextEdit):
# Finalise
QApplication.restoreOverrideCursor()
self.updateStatusMessage.emit(
self.tr("Opened Document: {0}").format(nwItem.itemName)
self.tr("Opened Document: {0}").format(self._nwItem.itemName)
)
return True
@@ -469,19 +467,17 @@ class GuiDocEditor(QPlainTextEdit):
)
return False
docText = self.getText()
cC, wC, pC = standardCounter(docText)
text = self.getText()
cC, wC, pC = standardCounter(text)
self._updateDocCounts(cC, wC, pC)
if not self._nwDocument.writeDocument(docText):
if not self._nwDocument.writeDocument(text):
saveOk = False
if self._nwDocument.hashError:
msgYes = SHARED.question(self.tr(
"This document has been changed outside of novelWriter "
"while it was open. Overwrite the file on disk?"
))
if msgYes:
saveOk = self._nwDocument.writeDocument(docText, forceWrite=True)
if self._nwDocument.hashError and SHARED.question(self.tr(
"This document has been changed outside of novelWriter "
"while it was open. Overwrite the file on disk?"
)):
saveOk = self._nwDocument.writeDocument(text, forceWrite=True)
if not saveOk:
SHARED.error(
@@ -494,10 +490,8 @@ class GuiDocEditor(QPlainTextEdit):
self.setDocumentChanged(False)
self.docTextChanged.emit(self._docHandle, self._lastEdit)
oldHeader = self._nwItem.mainHeading
oldCount = SHARED.project.index.getHandleHeaderCount(tHandle)
SHARED.project.index.scanText(tHandle, docText)
newHeader = self._nwItem.mainHeading
SHARED.project.index.scanText(tHandle, text)
newCount = SHARED.project.index.getHandleHeaderCount(tHandle)
if self._nwItem.itemClass == nwItemClass.NOVEL:
@@ -506,9 +500,6 @@ class GuiDocEditor(QPlainTextEdit):
else:
self.novelStructureChanged.emit()
if oldHeader != newHeader:
self.docFooter.updateInfo()
# Update the status bar
self.updateStatusMessage.emit(self.tr("Saved Document: {0}").format(self._nwItem.itemName))
@@ -589,7 +580,7 @@ class GuiDocEditor(QPlainTextEdit):
QTextDocument->toRawText instead of toPlainText. The former preserves
non-breaking spaces, the latter does not. We still want to get rid of
paragraph and line separators though.
See: https://doc.qt.io/qt-5/qtextdocument.html#toPlainText
See: https://doc.qt.io/qt-6/qtextdocument.html#toPlainText
"""
text = self._qDocument.toRawText()
text = text.replace(nwUnicode.U_LSEP, "\n") # Line separators
@@ -627,10 +618,9 @@ class GuiDocEditor(QPlainTextEdit):
def setCursorPosition(self, position: int) -> None:
"""Move the cursor to a given position in the document."""
nChars = self._qDocument.characterCount()
if nChars > 1 and isinstance(position, int):
if (chars := self._qDocument.characterCount()) > 1 and isinstance(position, int):
cursor = self.textCursor()
cursor.setPosition(minmax(position, 0, nChars-1))
cursor.setPosition(minmax(position, 0, chars-1))
self.setTextCursor(cursor)
self.centerCursor()
return
@@ -693,12 +683,10 @@ class GuiDocEditor(QPlainTextEdit):
def spellCheckDocument(self) -> None:
"""Rerun the highlighter to update spell checking status of the
currently loaded text. The fastest way to do this, at least as
of Qt 5.13, is to clear the text and put it back. This clears
the undo stack, so we only do it for big documents.
currently loaded text.
"""
logger.debug("Running spell checker")
start = time()
logger.debug("Running spell checker")
QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
self._qDocument.syntaxHighlighter.rehighlight()
QApplication.restoreOverrideCursor()
@@ -939,9 +927,7 @@ class GuiDocEditor(QPlainTextEdit):
* We also handle automatic scrolling here.
"""
self._lastActive = time()
isReturn = event.key() == Qt.Key.Key_Return
isReturn |= event.key() == Qt.Key.Key_Enter
if isReturn and self.docSearch.anyFocus():
if self.docSearch.anyFocus() and event.key() in (Qt.Key.Key_Return, Qt.Key.Key_Enter):
return
elif event == QKeySequence.StandardKey.Redo:
self.docAction(nwDocAction.REDO)
@@ -1094,7 +1080,7 @@ class GuiDocEditor(QPlainTextEdit):
if (block := self._qDocument.findBlock(pos)).isValid():
text = block.text()
if text.startswith("@") and added + removed == 1:
# Only run on single keypresses, otherwise it will trigger
# Only run on single character changes, or it will trigger
# at unwanted times when other changes are made to the document
cursor = self.textCursor()
bPos = cursor.positionInBlock()
@@ -1106,10 +1092,10 @@ class GuiDocEditor(QPlainTextEdit):
else:
self._completer.setVisible(False)
if self._doReplace and added == 1:
cursor = self.textCursor()
if self._autoReplace.process(text, cursor):
self._qDocument.syntaxHighlighter.rehighlightBlock(cursor.block())
if self._doReplace and added == 1:
cursor = self.textCursor()
if self._autoReplace.process(text, cursor):
self._qDocument.syntaxHighlighter.rehighlightBlock(cursor.block())
return
@@ -1123,11 +1109,10 @@ class GuiDocEditor(QPlainTextEdit):
def _insertCompletion(self, pos: int, length: int, text: str) -> None:
"""Insert choice from the completer menu."""
cursor = self.textCursor()
block = cursor.block()
if block.isValid():
pos += block.position()
cursor.setPosition(pos, QtMoveAnchor)
cursor.setPosition(pos + length, QtKeepAnchor)
if (block := cursor.block()).isValid():
check = pos + block.position()
cursor.setPosition(check, QtMoveAnchor)
cursor.setPosition(check + length, QtKeepAnchor)
cursor.insertText(text)
self._completer.hide()
return
@@ -1220,7 +1205,8 @@ class GuiDocEditor(QPlainTextEdit):
# Execute the context menu
if viewport := self.viewport():
ctxMenu.exec(viewport.mapToGlobal(pos))
ctxMenu.deleteLater()
ctxMenu.setParent(None)
return
@@ -1277,15 +1263,11 @@ class GuiDocEditor(QPlainTextEdit):
@pyqtSlot()
def _runSelCounter(self) -> None:
"""Update the selection word count."""
if self._docHandle is None:
return
if self._wCounterSel.isRunning():
logger.debug("Selection word counter is busy")
return
SHARED.runInThreadPool(self._wCounterSel)
if self._docHandle:
if self._wCounterSel.isRunning():
logger.debug("Selection word counter is busy")
return
SHARED.runInThreadPool(self._wCounterSel)
return
@pyqtSlot(int, int, int)
@@ -1565,8 +1547,10 @@ class GuiDocEditor(QPlainTextEdit):
return
def _wrapSelection(self, before: str, after: str | None = None, pos: int | None = None,
select: _SelectAction = _SelectAction.NO_DECISION) -> None:
def _wrapSelection(
self, before: str, after: str | None = None, pos: int | None = None,
select: _SelectAction = _SelectAction.NO_DECISION
) -> None:
"""Wrap the selected text in whatever is in tBefore and tAfter.
If there is no selection, the autoSelect setting decides the
action. AutoSelect will select the word under the cursor before
@@ -1928,8 +1912,9 @@ class GuiDocEditor(QPlainTextEdit):
self._qDocument.syntaxHighlighter.rehighlightBlock(block)
return
def _processTag(self, cursor: QTextCursor | None = None,
follow: bool = True, create: bool = False) -> nwTrinary:
def _processTag(
self, cursor: QTextCursor | None = None, follow: bool = True, create: bool = False
) -> nwTrinary:
"""Activated by Ctrl+Enter. Checks that we're in a block
starting with '@'. We then find the tag under the cursor and
check that it is not the tag itself. If all this is fine, we
@@ -2163,13 +2148,10 @@ class BackgroundWordCounter(QRunnable):
def __init__(self, docEditor: GuiDocEditor, forSelection: bool = False) -> None:
super().__init__()
self._docEditor = docEditor
self._forSelection = forSelection
self._isRunning = False
self.signals = BackgroundWordCounterSignals()
return
def isRunning(self) -> bool:
@@ -2851,7 +2833,7 @@ class GuiDocEditHeader(QWidget):
self.setAutoFillBackground(True)
# Title Label
self.itemTitle = NColourLabel("", self, faded=SHARED.theme.fadedText)
self.itemTitle = NColorLabel("", self, faded=SHARED.theme.fadedText)
self.itemTitle.setMargin(0)
self.itemTitle.setContentsMargins(0, 0, 0, 0)
self.itemTitle.setAutoFillBackground(True)
@@ -2969,11 +2951,11 @@ class GuiDocEditHeader(QWidget):
self.minmaxButton.setStyleSheet(buttonStyle)
self.closeButton.setStyleSheet(buttonStyle)
self.matchColours()
self.matchColors()
return
def matchColours(self) -> None:
def matchColors(self) -> None:
"""Update the colours of the widget to match those of the syntax
theme rather than the main GUI.
"""
@@ -3079,42 +3061,30 @@ class GuiDocEditFooter(QWidget):
# Status
self.statusIcon = QLabel("", self)
self.statusIcon.setContentsMargins(0, 0, 0, 0)
self.statusIcon.setFixedHeight(iPx)
self.statusIcon.setAlignment(QtAlignLeftTop)
self.statusText = QLabel(self.tr("Status"), self)
self.statusText.setIndent(0)
self.statusText.setMargin(0)
self.statusText.setContentsMargins(0, 0, 0, 0)
self.statusText = QLabel("", self)
self.statusText.setAutoFillBackground(True)
self.statusText.setFixedHeight(fPx)
self.statusText.setAlignment(QtAlignLeftTop)
# Lines
self.linesIcon = QLabel("", self)
self.linesIcon.setContentsMargins(0, 0, 0, 0)
self.linesIcon.setFixedHeight(iPx)
self.linesIcon.setAlignment(QtAlignLeftTop)
self.linesText = QLabel("", self)
self.linesText.setIndent(0)
self.linesText.setMargin(0)
self.linesText.setContentsMargins(0, 0, 0, 0)
self.linesText.setAutoFillBackground(True)
self.linesText.setFixedHeight(fPx)
self.linesText.setAlignment(QtAlignLeftTop)
# Words
self.wordsIcon = QLabel("", self)
self.wordsIcon.setContentsMargins(0, 0, 0, 0)
self.wordsIcon.setFixedHeight(iPx)
self.wordsIcon.setAlignment(QtAlignLeftTop)
self.wordsText = QLabel("", self)
self.wordsText.setIndent(0)
self.wordsText.setMargin(0)
self.wordsText.setContentsMargins(0, 0, 0, 0)
self.wordsText.setAutoFillBackground(True)
self.wordsText.setFixedHeight(fPx)
self.wordsText.setAlignment(QtAlignLeftTop)
@@ -3167,10 +3137,10 @@ class GuiDocEditFooter(QWidget):
iPx = round(0.9*SHARED.theme.baseIconHeight)
self.linesIcon.setPixmap(SHARED.theme.getPixmap("lines", (iPx, iPx)))
self.wordsIcon.setPixmap(SHARED.theme.getPixmap("stats", (iPx, iPx)))
self.matchColours()
self.matchColors()
return
def matchColours(self) -> None:
def matchColors(self) -> None:
"""Update the colours of the widget to match those of the syntax
theme rather than the main GUI.
"""
+10 -9
View File
@@ -45,7 +45,7 @@ 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
from novelwriter.extensions.configlayout import NColourLabel
from novelwriter.extensions.configlayout import NColorLabel
from novelwriter.extensions.eventfilters import WheelEventFilter
from novelwriter.extensions.modified import NIconToolButton
from novelwriter.formats.shared import TextDocumentTheme
@@ -167,8 +167,8 @@ class GuiDocViewer(QTextBrowser):
palette.setColor(QPalette.ColorRole.Base, syntax.back)
palette.setColor(QPalette.ColorRole.Text, syntax.text)
viewport.setPalette(palette)
self.docHeader.matchColours()
self.docFooter.matchColours()
self.docHeader.matchColors()
self.docFooter.matchColors()
# Update theme colours
self._docTheme.text = syntax.text
@@ -424,7 +424,8 @@ class GuiDocViewer(QTextBrowser):
# Open the context menu
if viewport := self.viewport():
ctxMenu.exec(viewport.mapToGlobal(point))
ctxMenu.deleteLater()
ctxMenu.setParent(None)
return
@@ -643,7 +644,7 @@ class GuiDocViewHeader(QWidget):
self.setAutoFillBackground(True)
# Title Label
self.itemTitle = NColourLabel("", self, faded=SHARED.theme.fadedText)
self.itemTitle = NColorLabel("", self, faded=SHARED.theme.fadedText)
self.itemTitle.setMargin(0)
self.itemTitle.setContentsMargins(0, 0, 0, 0)
self.itemTitle.setAutoFillBackground(True)
@@ -774,11 +775,11 @@ class GuiDocViewHeader(QWidget):
self.refreshButton.setStyleSheet(buttonStyle)
self.closeButton.setStyleSheet(buttonStyle)
self.matchColours()
self.matchColors()
return
def matchColours(self) -> None:
def matchColors(self) -> None:
"""Update the colours of the widget to match those of the syntax
theme rather than the main GUI.
"""
@@ -960,11 +961,11 @@ class GuiDocViewFooter(QWidget):
self.showComments.setStyleSheet(buttonStyle)
self.showSynopsis.setStyleSheet(buttonStyle)
self.matchColours()
self.matchColors()
return
def matchColours(self) -> None:
def matchColors(self) -> None:
"""Update the colours of the widget to match those of the syntax
theme rather than the main GUI.
"""
+1
View File
@@ -90,6 +90,7 @@ class GuiItemDetails(QWidget):
self.statusData = QLabel("", self)
self.statusData.setFont(fntValue)
self.statusData.setAlignment(QtAlignLeft)
self.statusData.setWordWrap(True)
# Class
self.className = QLabel(self.tr("Class"), self)
+3 -3
View File
@@ -46,7 +46,7 @@ from novelwriter.common import checkInt, formatFileFilter
from novelwriter.constants import nwKeyWords, nwLabels, nwStats, nwStyles, trConst
from novelwriter.enum import nwChange, nwDocMode, nwItemClass, nwItemLayout, nwItemType, nwOutline
from novelwriter.error import logException
from novelwriter.extensions.configlayout import NColourLabel
from novelwriter.extensions.configlayout import NColorLabel
from novelwriter.extensions.novelselector import NovelSelector
from novelwriter.types import (
QtAlignLeftTop, QtAlignRight, QtAlignRightTop, QtDecoration,
@@ -222,8 +222,8 @@ class GuiOutlineToolBar(QToolBar):
stretch.setSizePolicy(QtSizeExpanding, QtSizeExpanding)
# Novel Selector
self.novelLabel = NColourLabel(
self.tr("Outline of"), self, scale=NColourLabel.HEADER_SCALE, bold=True
self.novelLabel = NColorLabel(
self.tr("Outline of"), self, scale=NColorLabel.HEADER_SCALE, bold=True
)
self.novelLabel.setContentsMargins(0, 0, 12, 0)
+2 -1
View File
@@ -969,7 +969,8 @@ class GuiProjectTree(QTreeView):
if viewport := self.viewport():
ctxMenu.exec(viewport.mapToGlobal(point))
ctxMenu.deleteLater()
ctxMenu.setParent(None)
return
+41 -41
View File
@@ -250,26 +250,26 @@ class GuiTheme:
# Icons
sec = "Icons"
if parser.has_section(sec):
self.iconCache.setIconColor("default", self._parseColour(parser, sec, "default"))
self.iconCache.setIconColor("faded", self._parseColour(parser, sec, "faded"))
self.iconCache.setIconColor("red", self._parseColour(parser, sec, "red"))
self.iconCache.setIconColor("orange", self._parseColour(parser, sec, "orange"))
self.iconCache.setIconColor("yellow", self._parseColour(parser, sec, "yellow"))
self.iconCache.setIconColor("green", self._parseColour(parser, sec, "green"))
self.iconCache.setIconColor("aqua", self._parseColour(parser, sec, "aqua"))
self.iconCache.setIconColor("blue", self._parseColour(parser, sec, "blue"))
self.iconCache.setIconColor("purple", self._parseColour(parser, sec, "purple"))
self.iconCache.setIconColor("default", self._parseColor(parser, sec, "default"))
self.iconCache.setIconColor("faded", self._parseColor(parser, sec, "faded"))
self.iconCache.setIconColor("red", self._parseColor(parser, sec, "red"))
self.iconCache.setIconColor("orange", self._parseColor(parser, sec, "orange"))
self.iconCache.setIconColor("yellow", self._parseColor(parser, sec, "yellow"))
self.iconCache.setIconColor("green", self._parseColor(parser, sec, "green"))
self.iconCache.setIconColor("aqua", self._parseColor(parser, sec, "aqua"))
self.iconCache.setIconColor("blue", self._parseColor(parser, sec, "blue"))
self.iconCache.setIconColor("purple", self._parseColor(parser, sec, "purple"))
# Project
sec = "Project"
if parser.has_section(sec):
self.iconCache.setIconColor("root", self._parseColour(parser, sec, "root"))
self.iconCache.setIconColor("folder", self._parseColour(parser, sec, "folder"))
self.iconCache.setIconColor("file", self._parseColour(parser, sec, "file"))
self.iconCache.setIconColor("title", self._parseColour(parser, sec, "title"))
self.iconCache.setIconColor("chapter", self._parseColour(parser, sec, "chapter"))
self.iconCache.setIconColor("scene", self._parseColour(parser, sec, "scene"))
self.iconCache.setIconColor("note", self._parseColour(parser, sec, "note"))
self.iconCache.setIconColor("root", self._parseColor(parser, sec, "root"))
self.iconCache.setIconColor("folder", self._parseColor(parser, sec, "folder"))
self.iconCache.setIconColor("file", self._parseColor(parser, sec, "file"))
self.iconCache.setIconColor("title", self._parseColor(parser, sec, "title"))
self.iconCache.setIconColor("chapter", self._parseColor(parser, sec, "chapter"))
self.iconCache.setIconColor("scene", self._parseColor(parser, sec, "scene"))
self.iconCache.setIconColor("note", self._parseColor(parser, sec, "note"))
# Palette
sec = "Palette"
@@ -292,9 +292,9 @@ class GuiTheme:
# GUI
sec = "GUI"
if parser.has_section(sec):
self.helpText = self._parseColour(parser, sec, "helptext")
self.fadedText = self._parseColour(parser, sec, "fadedtext")
self.errorText = self._parseColour(parser, sec, "errortext")
self.helpText = self._parseColor(parser, sec, "helptext")
self.fadedText = self._parseColor(parser, sec, "fadedtext")
self.errorText = self._parseColor(parser, sec, "errortext")
# Update Dependant Colours
# Based on: https://github.com/qt/qtbase/blob/dev/src/gui/kernel/qplatformtheme.cpp
@@ -399,26 +399,26 @@ class GuiTheme:
sec = "Syntax"
syntax = SyntaxColors()
if parser.has_section(sec):
syntax.back = self._parseColour(parser, sec, "background")
syntax.text = self._parseColour(parser, sec, "text")
syntax.link = self._parseColour(parser, sec, "link")
syntax.head = self._parseColour(parser, sec, "headertext")
syntax.headH = self._parseColour(parser, sec, "headertag")
syntax.emph = self._parseColour(parser, sec, "emphasis")
syntax.dialN = self._parseColour(parser, sec, "dialog")
syntax.dialA = self._parseColour(parser, sec, "altdialog")
syntax.hidden = self._parseColour(parser, sec, "hidden")
syntax.note = self._parseColour(parser, sec, "note")
syntax.code = self._parseColour(parser, sec, "shortcode")
syntax.key = self._parseColour(parser, sec, "keyword")
syntax.tag = self._parseColour(parser, sec, "tag")
syntax.val = self._parseColour(parser, sec, "value")
syntax.opt = self._parseColour(parser, sec, "optional")
syntax.spell = self._parseColour(parser, sec, "spellcheckline")
syntax.error = self._parseColour(parser, sec, "errorline")
syntax.repTag = self._parseColour(parser, sec, "replacetag")
syntax.mod = self._parseColour(parser, sec, "modifier")
syntax.mark = self._parseColour(parser, sec, "texthighlight")
syntax.back = self._parseColor(parser, sec, "background")
syntax.text = self._parseColor(parser, sec, "text")
syntax.link = self._parseColor(parser, sec, "link")
syntax.head = self._parseColor(parser, sec, "headertext")
syntax.headH = self._parseColor(parser, sec, "headertag")
syntax.emph = self._parseColor(parser, sec, "emphasis")
syntax.dialN = self._parseColor(parser, sec, "dialog")
syntax.dialA = self._parseColor(parser, sec, "altdialog")
syntax.hidden = self._parseColor(parser, sec, "hidden")
syntax.note = self._parseColor(parser, sec, "note")
syntax.code = self._parseColor(parser, sec, "shortcode")
syntax.key = self._parseColor(parser, sec, "keyword")
syntax.tag = self._parseColor(parser, sec, "tag")
syntax.val = self._parseColor(parser, sec, "value")
syntax.opt = self._parseColor(parser, sec, "optional")
syntax.spell = self._parseColor(parser, sec, "spellcheckline")
syntax.error = self._parseColor(parser, sec, "errorline")
syntax.repTag = self._parseColor(parser, sec, "replacetag")
syntax.mod = self._parseColor(parser, sec, "modifier")
syntax.mark = self._parseColor(parser, sec, "texthighlight")
self.syntaxMeta = meta
self.syntaxTheme = syntax
@@ -513,7 +513,7 @@ class GuiTheme:
return
def _parseColour(self, parser: NWConfigParser, section: str, name: str) -> QColor:
def _parseColor(self, parser: NWConfigParser, section: str, name: str) -> QColor:
"""Parse a colour value from a config string."""
return QColor(*parser.rdIntList(section, name, [0, 0, 0, 255]))
@@ -521,7 +521,7 @@ class GuiTheme:
self, parser: NWConfigParser, section: str, name: str, value: QPalette.ColorRole
) -> None:
"""Set a palette colour value from a config string."""
self._guiPalette.setBrush(value, self._parseColour(parser, section, name))
self._guiPalette.setBrush(value, self._parseColor(parser, section, name))
return
def _buildStyleSheets(self, palette: QPalette) -> None:
+1 -1
View File
@@ -1064,7 +1064,7 @@ class GuiMain(QMainWindow):
if syntax:
SHARED.theme.loadSyntax()
self.docEditor.updateSyntaxColours()
self.docEditor.updateSyntaxColors()
self.docEditor.initEditor()
self.docViewer.initViewer()
+1 -1
View File
@@ -773,7 +773,7 @@ class _PreviewWidget(QTextBrowser):
self.buildProgress.setVisible(False)
self.buildProgress.setMaximum(1)
self.buildProgress.setValue(0)
self.buildProgress.setColours(
self.buildProgress.setColors(
back=QColor(255, 255, 255, 224),
track=QColor(196, 196, 196, 128),
text=QColor(0, 0, 0)
+3 -3
View File
@@ -41,7 +41,7 @@ from novelwriter.common import describeFont, fontMatcher, qtAddAction, qtLambda
from novelwriter.constants import nwHeadFmt, nwKeyWords, nwLabels, nwStyles, trConst
from novelwriter.core.buildsettings import BuildSettings, FilterMode
from novelwriter.extensions.configlayout import (
NColourLabel, NFixedPage, NScrollableForm, NScrollablePage
NColorLabel, NFixedPage, NScrollableForm, NScrollablePage
)
from novelwriter.extensions.modified import (
NComboBox, NDoubleSpinBox, NIconToolButton, NSpinBox, NToolDialog
@@ -92,9 +92,9 @@ class GuiBuildSettings(NToolDialog):
)
# Title
self.titleLabel = NColourLabel(
self.titleLabel = NColorLabel(
self.tr("Manuscript Build Settings"), self, color=SHARED.theme.helpText,
scale=NColourLabel.HEADER_SCALE, indent=4,
scale=NColorLabel.HEADER_SCALE, indent=4,
)
# Settings Name
+9 -9
View File
@@ -37,7 +37,7 @@ from PyQt6.QtWidgets import (
from novelwriter import SHARED
from novelwriter.common import formatTime, numberToRoman
from novelwriter.constants import nwUnicode
from novelwriter.extensions.configlayout import NColourLabel, NFixedPage, NScrollablePage
from novelwriter.extensions.configlayout import NColorLabel, NFixedPage, NScrollablePage
from novelwriter.extensions.modified import NNonBlockingDialog
from novelwriter.extensions.novelselector import NovelSelector
from novelwriter.extensions.pagedsidebar import NPagedSideBar
@@ -67,9 +67,9 @@ class GuiNovelDetails(NNonBlockingDialog):
)
# Title
self.titleLabel = NColourLabel(
self.titleLabel = NColorLabel(
self.tr("Novel Details"), self, color=SHARED.theme.helpText,
scale=NColourLabel.HEADER_SCALE, indent=4,
scale=NColorLabel.HEADER_SCALE, indent=4,
)
# Novel Selector
@@ -188,9 +188,9 @@ class _OverviewPage(NScrollablePage):
super().__init__(parent=parent)
# Project Info
self.projLabel = NColourLabel(
self.projLabel = NColorLabel(
self.tr("Project"), self, color=SHARED.theme.helpText,
scale=NColourLabel.HEADER_SCALE
scale=NColorLabel.HEADER_SCALE
)
self.projName = QLabel("", self)
@@ -212,9 +212,9 @@ class _OverviewPage(NScrollablePage):
self.projForm.setVerticalSpacing(4)
# Novel Info
self.novelLabel = NColourLabel(
self.novelLabel = NColorLabel(
self.tr("Selected Novel"), self, color=SHARED.theme.helpText,
scale=NColourLabel.HEADER_SCALE
scale=NColorLabel.HEADER_SCALE
)
self.novelName = QLabel("", self)
@@ -302,9 +302,9 @@ class _ContentsPage(NFixedPage):
options = SHARED.project.options
# Title
self.contentLabel = NColourLabel(
self.contentLabel = NColorLabel(
self.tr("Table of Contents"), self, color=SHARED.theme.helpText,
scale=NColourLabel.HEADER_SCALE
scale=NColorLabel.HEADER_SCALE
)
# Contents Tree
+1 -1
View File
@@ -366,7 +366,7 @@ class _OpenProjectPage(QWidget):
action = qtAddAction(ctxMenu, self.tr("Remove Project"))
action.triggered.connect(self._deleteSelectedItem)
ctxMenu.exec(self.mapToGlobal(pos))
ctxMenu.deleteLater()
ctxMenu.setParent(None)
return
##
+1 -1
View File
@@ -42,7 +42,7 @@ def testExtProgressBars_NProgressCircle(qtbot):
dialog.show()
dialog.resize(200, 200)
progress.setColours(
progress.setColors(
QColor(255, 255, 255), QColor(255, 192, 192),
QColor(255, 0, 0), QColor(0, 0, 0),
)
+2
View File
@@ -333,6 +333,7 @@ def testGuiEditor_MetaData(qtbot, nwGUI, projPath, mockRnd):
def testGuiEditor_ContextMenu(monkeypatch, qtbot, nwGUI, projPath, mockRnd):
"""Test the editor context menu."""
monkeypatch.setattr(QMenu, "exec", lambda *a: None)
monkeypatch.setattr(QMenu, "setParent", lambda *a: None)
buildTestProject(nwGUI, projPath)
assert nwGUI.openDocument(C.hSceneDoc) is True
@@ -475,6 +476,7 @@ def testGuiEditor_ContextMenu(monkeypatch, qtbot, nwGUI, projPath, mockRnd):
def testGuiEditor_SpellChecking(qtbot, monkeypatch, nwGUI, projPath, ipsumText, mockRnd):
"""Test the document spell checker."""
monkeypatch.setattr(QMenu, "exec", lambda *a: None)
monkeypatch.setattr(QMenu, "setParent", lambda *a: None)
buildTestProject(nwGUI, projPath)
assert nwGUI.openDocument(C.hSceneDoc) is True
+6 -6
View File
@@ -79,12 +79,12 @@ def testGuiTheme_Main(qtbot, nwGUI, tstPaths):
}
# Test the parser for several valid and invalid values
assert mainTheme._parseColour(parser, "Palette", "colour1").getRgb() == (100, 150, 200, 255)
assert mainTheme._parseColour(parser, "Palette", "colour2").getRgb() == (100, 150, 200, 250)
assert mainTheme._parseColour(parser, "Palette", "colour3").getRgb() == (100, 150, 200, 250)
assert mainTheme._parseColour(parser, "Palette", "colour4").getRgb() == (250, 250, 0, 255)
assert mainTheme._parseColour(parser, "Palette", "colour5").getRgb() == (0, 0, 0, 0)
assert mainTheme._parseColour(parser, "Palette", "colour6").getRgb() == (0, 127, 255, 255)
assert mainTheme._parseColor(parser, "Palette", "colour1").getRgb() == (100, 150, 200, 255)
assert mainTheme._parseColor(parser, "Palette", "colour2").getRgb() == (100, 150, 200, 250)
assert mainTheme._parseColor(parser, "Palette", "colour3").getRgb() == (100, 150, 200, 250)
assert mainTheme._parseColor(parser, "Palette", "colour4").getRgb() == (250, 250, 0, 255)
assert mainTheme._parseColor(parser, "Palette", "colour5").getRgb() == (0, 0, 0, 0)
assert mainTheme._parseColor(parser, "Palette", "colour6").getRgb() == (0, 127, 255, 255)
# The palette should load with the parsed values
mainTheme._setPalette(parser, "Palette", "colour1", QPalette.ColorRole.Window)
+1
View File
@@ -70,6 +70,7 @@ def testToolWelcome_Main(qtbot, monkeypatch, nwGUI, fncPath):
def testToolWelcome_Open(qtbot, monkeypatch, nwGUI, fncPath):
"""Test the open tab in the Welcome window."""
monkeypatch.setattr(QMenu, "exec", lambda *a: None)
monkeypatch.setattr(QMenu, "setParent", lambda *a: None)
CONFIG.recentProjects.update("/stuff/project_one", "Project One", 12345, 1690000000)
CONFIG.recentProjects.update("/stuff/project_two", "Project Two", 54321, 1700000000)