Merge 2.7.2 bugfixes into main (#2417)

This commit is contained in:
Veronica Berglyd Olsen
2025-06-18 20:30:41 +02:00
committed by GitHub
9 changed files with 104 additions and 78 deletions
+2 -2
View File
@@ -44,7 +44,7 @@ from novelwriter.common import (
NWConfigParser, checkInt, checkPath, describeFont, fontMatcher, NWConfigParser, checkInt, checkPath, describeFont, fontMatcher,
formatTimeStamp, processDialogSymbols, simplified formatTimeStamp, processDialogSymbols, simplified
) )
from novelwriter.constants import nwFiles, nwHtmlUnicode, nwQuotes, nwUnicode from novelwriter.constants import nwFiles, nwQuotes, nwUnicode
from novelwriter.enum import nwTheme from novelwriter.enum import nwTheme
from novelwriter.error import formatException, logException from novelwriter.error import formatException, logException
@@ -899,7 +899,7 @@ class Config:
""" """
self.splashMessage(f"Initialising {kind} font: {font.family()}") self.splashMessage(f"Initialising {kind} font: {font.family()}")
metrics = QFontMetrics(font) metrics = QFontMetrics(font)
for char in nwHtmlUnicode.U_TO_H.keys(): for char in nwUnicode.UI_SYMBOLS:
if not metrics.inFont(char): # type: ignore if not metrics.inFont(char): # type: ignore
logger.warning("No glyph U+%04x in font", ord(char)) # pragma: no cover logger.warning("No glyph U+%04x in font", ord(char)) # pragma: no cover
return return
+12 -19
View File
@@ -598,21 +598,14 @@ class nwUnicode:
U_TIMES = "\u00d7" # Multiplication sign U_TIMES = "\u00d7" # Multiplication sign
U_DIVIDE = "\u00f7" # Division sign U_DIVIDE = "\u00f7" # Division sign
# Arrows
U_UTRI = "\u25b2" # Up-pointing triangle
U_UTRIS = "\u25b4" # Up-pointing triangle, small
U_RTRI = "\u25b6" # Right-pointing triangle
U_RTRIS = "\u25b8" # Right-pointing triangle, small
U_DTRI = "\u25bc" # Down-pointing triangle
U_DTRIS = "\u25be" # Down-pointing triangle, small
U_LTRI = "\u25c0" # Left-pointing triangle
U_LTRIS = "\u25c2" # Left-pointing triangle, small
# Special # Special
U_UNKN = "\ufffd" # Unknown character U_UNKN = "\ufffd" # Unknown character
U_NAC1 = "\ufffe" # Not a character U_NAC1 = "\ufffe" # Not a character
U_NAC2 = "\uffff" # Not a character U_NAC2 = "\uffff" # Not a character
# Placeholders
U_LBREAK = "\u21b2" # Downwards Arrow With Tip Leftwards
# HTML Equivalents # HTML Equivalents
# ================ # ================
@@ -667,15 +660,15 @@ class nwUnicode:
H_TIMES = "×" H_TIMES = "×"
H_DIVIDE = "÷" H_DIVIDE = "÷"
# Arrows # Unicode symbols expected to be used on the UI
H_UTRI = "▲" UI_SYMBOLS: Final[list[str]] = [
H_UTRIS = "▴" U_QUOT, U_APOS, U_LAQUO, U_RAQUO, U_LSQUO, U_RSQUO, U_SBQUO, U_SUQUO,
H_RTRI = "▶" U_LDQUO, U_RDQUO, U_BDQUO, U_UDQUO, U_LSAQUO, U_RSAQUO, U_BDRQUO,
H_RTRIS = "▸" U_LCQUO, U_RCQUO, U_LWCQUO, U_RWCQUO, U_FGDASH, U_ENDASH, U_EMDASH,
H_DTRI = "▼" U_HBAR, U_HELLIP, U_MAPOS, U_PRIME, U_DPRIME, U_NBSP, U_THSP, U_THNBSP,
H_DTRIS = "▾" U_ENSP, U_EMSP, U_MMSP, U_CHECK, U_CROSS, U_BULL, U_TRBULL, U_HYBULL,
H_LTRI = "◀" U_FLOWER, U_PERMIL, U_DEGREE, U_MINUS, U_TIMES, U_DIVIDE, U_LBREAK,
H_LTRIS = "◂" ]
class nwHtmlUnicode: class nwHtmlUnicode:
+23 -17
View File
@@ -1169,12 +1169,18 @@ class Tokenizer(ABC):
class HeadingFormatter: class HeadingFormatter:
def __init__(self, project: NWProject) -> None: def __init__(
self,
project: NWProject,
chapter: int = 0,
scene: int = 0,
absolute: int = 0,
) -> None:
self._project = project self._project = project
self._handle = None self._handle = None
self._chCount = 0 self._chapter = chapter
self._scChCount = 0 self._scene = scene
self._scAbsCount = 0 self._absolute = absolute
return return
def setHandle(self, tHandle: str | None) -> None: def setHandle(self, tHandle: str | None) -> None:
@@ -1184,42 +1190,42 @@ class HeadingFormatter:
def incChapter(self) -> None: def incChapter(self) -> None:
"""Increment the chapter counter.""" """Increment the chapter counter."""
self._chCount += 1 self._chapter += 1
return return
def incScene(self) -> None: def incScene(self) -> None:
"""Increment the scene counters.""" """Increment the scene counters."""
self._scChCount += 1 self._scene += 1
self._scAbsCount += 1 self._absolute += 1
return return
def resetAll(self) -> None: def resetAll(self) -> None:
"""Reset all counters.""" """Reset all counters."""
self._chCount = 0 self._chapter = 0
self._scChCount = 0 self._scene = 0
self._scAbsCount = 0 self._absolute = 0
return return
def resetScene(self) -> None: def resetScene(self) -> None:
"""Reset the chapter scene counter.""" """Reset the chapter scene counter."""
self._scChCount = 0 self._scene = 0
return return
def apply(self, hFormat: str, text: str, nHead: int) -> str: def apply(self, hFormat: str, text: str, nHead: int) -> str:
"""Apply formatting to a specific heading.""" """Apply formatting to a specific heading."""
hFormat = hFormat.replace(nwHeadFmt.TITLE, text) hFormat = hFormat.replace(nwHeadFmt.TITLE, text)
hFormat = hFormat.replace(nwHeadFmt.BR, "\n") hFormat = hFormat.replace(nwHeadFmt.BR, "\n")
hFormat = hFormat.replace(nwHeadFmt.CH_NUM, str(self._chCount)) hFormat = hFormat.replace(nwHeadFmt.CH_NUM, str(self._chapter))
hFormat = hFormat.replace(nwHeadFmt.SC_NUM, str(self._scChCount)) hFormat = hFormat.replace(nwHeadFmt.SC_NUM, str(self._scene))
hFormat = hFormat.replace(nwHeadFmt.SC_ABS, str(self._scAbsCount)) hFormat = hFormat.replace(nwHeadFmt.SC_ABS, str(self._absolute))
if nwHeadFmt.CH_WORD in hFormat: if nwHeadFmt.CH_WORD in hFormat:
chWord = self._project.localLookup(self._chCount) chWord = self._project.localLookup(self._chapter)
hFormat = hFormat.replace(nwHeadFmt.CH_WORD, chWord) hFormat = hFormat.replace(nwHeadFmt.CH_WORD, chWord)
if nwHeadFmt.CH_ROML in hFormat: if nwHeadFmt.CH_ROML in hFormat:
chRom = numberToRoman(self._chCount, toLower=True) chRom = numberToRoman(self._chapter, toLower=True)
hFormat = hFormat.replace(nwHeadFmt.CH_ROML, chRom) hFormat = hFormat.replace(nwHeadFmt.CH_ROML, chRom)
if nwHeadFmt.CH_ROMU in hFormat: if nwHeadFmt.CH_ROMU in hFormat:
chRom = numberToRoman(self._chCount, toLower=False) chRom = numberToRoman(self._chapter, toLower=False)
hFormat = hFormat.replace(nwHeadFmt.CH_ROMU, chRom) hFormat = hFormat.replace(nwHeadFmt.CH_ROMU, chRom)
if nwHeadFmt.CHAR_POV in hFormat or nwHeadFmt.CHAR_FOCUS in hFormat: if nwHeadFmt.CHAR_POV in hFormat or nwHeadFmt.CHAR_FOCUS in hFormat:
+7 -4
View File
@@ -40,8 +40,9 @@ from novelwriter.formats.shared import BlockFmt, BlockTyp, T_Formats, TextFmt, s
from novelwriter.formats.tokenizer import HEADINGS, Tokenizer from novelwriter.formats.tokenizer import HEADINGS, Tokenizer
from novelwriter.types import ( from novelwriter.types import (
QtAlignAbsolute, QtAlignCenter, QtAlignJustify, QtAlignLeft, QtAlignRight, QtAlignAbsolute, QtAlignCenter, QtAlignJustify, QtAlignLeft, QtAlignRight,
QtKeepAnchor, QtMoveAnchor, QtPageBreakAfter, QtPageBreakBefore, QtKeepAnchor, QtMoveAnchor, QtPageBreakAfter, QtPageBreakAuto,
QtPropLineHeight, QtTransparent, QtVAlignNormal, QtVAlignSub, QtVAlignSuper QtPageBreakBefore, QtPropLineHeight, QtTransparent, QtVAlignNormal,
QtVAlignSub, QtVAlignSuper
) )
if TYPE_CHECKING: if TYPE_CHECKING:
@@ -253,8 +254,10 @@ class ToQTextDocument(Tokenizer):
elif tType in HEADINGS: elif tType in HEADINGS:
bFmt, cFmt = self._genHeadStyle(tType, tMeta, bFmt) bFmt, cFmt = self._genHeadStyle(tType, tMeta, bFmt)
newBlock(cursor, bFmt) for tPart in tText.split("\n"):
cursor.insertText(tText, cFmt) newBlock(cursor, bFmt)
cursor.insertText(tPart, cFmt)
bFmt.setPageBreakPolicy(QtPageBreakAuto)
elif tType == BlockTyp.SEP: elif tType == BlockTyp.SEP:
newBlock(cursor, bFmt) newBlock(cursor, bFmt)
+4 -7
View File
@@ -43,7 +43,7 @@ from PyQt6.QtWidgets import (
from novelwriter import CONFIG, SHARED from novelwriter import CONFIG, SHARED
from novelwriter.common import fuzzyTime, qtLambda from novelwriter.common import fuzzyTime, qtLambda
from novelwriter.constants import nwLabels, nwStats, trStats from novelwriter.constants import nwHeadFmt, nwLabels, nwStats, nwUnicode, trStats
from novelwriter.core.buildsettings import BuildCollection, BuildSettings from novelwriter.core.buildsettings import BuildCollection, BuildSettings
from novelwriter.core.docbuild import NWBuildDocument from novelwriter.core.docbuild import NWBuildDocument
from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton, NToolDialog from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton, NToolDialog
@@ -595,11 +595,7 @@ class _DetailsWidget(QWidget):
item.addChild(sub) item.addChild(sub)
# Headings # Headings
hFmt = HeadingFormatter(SHARED.project) hFmt = HeadingFormatter(SHARED.project, 7, 5, 23)
hFmt.incChapter()
hFmt.incScene()
hFmt.resetScene()
hFmt.incScene()
title = self.tr("Title") title = self.tr("Title")
hidden = self.tr("Hidden") hidden = self.tr("Hidden")
@@ -620,7 +616,8 @@ class _DetailsWidget(QWidget):
if build.getBool(hHide): if build.getBool(hHide):
sub.setText(1, f"[{hidden}]") sub.setText(1, f"[{hidden}]")
else: else:
sub.setText(1, hFmt.apply(build.getStr(hFormat), title, 0)) preview = build.getStr(hFormat).replace(nwHeadFmt.BR, nwUnicode.U_LBREAK)
sub.setText(1, hFmt.apply(preview, title, 0))
item.addChild(sub) item.addChild(sub)
# Text Content # Text Content
+19 -15
View File
@@ -38,7 +38,7 @@ from PyQt6.QtWidgets import (
from novelwriter import CONFIG, SHARED from novelwriter import CONFIG, SHARED
from novelwriter.common import describeFont, fontMatcher, qtAddAction, qtLambda from novelwriter.common import describeFont, fontMatcher, qtAddAction, qtLambda
from novelwriter.constants import nwHeadFmt, nwKeyWords, nwLabels, trConst from novelwriter.constants import nwHeadFmt, nwKeyWords, nwLabels, nwUnicode, trConst
from novelwriter.core.buildsettings import BuildSettings, FilterMode from novelwriter.core.buildsettings import BuildSettings, FilterMode
from novelwriter.extensions.configlayout import ( from novelwriter.extensions.configlayout import (
NColorLabel, NFixedPage, NScrollableForm, NScrollablePage NColorLabel, NFixedPage, NScrollableForm, NScrollablePage
@@ -795,12 +795,15 @@ class _HeadingsTab(NScrollablePage):
def loadContent(self) -> None: def loadContent(self) -> None:
"""Populate the widgets.""" """Populate the widgets."""
self.fmtPart.setText(self._build.getStr("headings.fmtPart")) def fmtBreak(text: str) -> str:
self.fmtChapter.setText(self._build.getStr("headings.fmtChapter")) return text.replace(nwHeadFmt.BR, nwUnicode.U_LBREAK)
self.fmtUnnumbered.setText(self._build.getStr("headings.fmtUnnumbered"))
self.fmtScene.setText(self._build.getStr("headings.fmtScene")) self.fmtPart.setText(fmtBreak(self._build.getStr("headings.fmtPart")))
self.fmtAScene.setText(self._build.getStr("headings.fmtAltScene")) self.fmtChapter.setText(fmtBreak(self._build.getStr("headings.fmtChapter")))
self.fmtSection.setText(self._build.getStr("headings.fmtSection")) self.fmtUnnumbered.setText(fmtBreak(self._build.getStr("headings.fmtUnnumbered")))
self.fmtScene.setText(fmtBreak(self._build.getStr("headings.fmtScene")))
self.fmtAScene.setText(fmtBreak(self._build.getStr("headings.fmtAltScene")))
self.fmtSection.setText(fmtBreak(self._build.getStr("headings.fmtSection")))
self.swtPart.setChecked(self._build.getBool("headings.hidePart")) self.swtPart.setChecked(self._build.getBool("headings.hidePart"))
self.swtChapter.setChecked(self._build.getBool("headings.hideChapter")) self.swtChapter.setChecked(self._build.getBool("headings.hideChapter"))
@@ -880,7 +883,7 @@ class _HeadingsTab(NScrollablePage):
text = "" text = ""
label = self.tr("None") label = self.tr("None")
self.editTextBox.setPlainText(text.replace(nwHeadFmt.BR, "\n")) self.editTextBox.setPlainText(text.replace(nwUnicode.U_LBREAK, "\n"))
self.lblEditForm.setText(self.tr("Editing: {0}").format(label)) self.lblEditForm.setText(self.tr("Editing: {0}").format(label))
return return
@@ -893,25 +896,26 @@ class _HeadingsTab(NScrollablePage):
def _saveFormat(self) -> None: def _saveFormat(self) -> None:
"""Save the format from the edit text box.""" """Save the format from the edit text box."""
heading = self._editing heading = self._editing
text = self.editTextBox.toPlainText().strip().replace("\n", nwHeadFmt.BR) text = self.editTextBox.toPlainText().strip().replace("\n", nwUnicode.U_LBREAK)
value = text.replace(nwUnicode.U_LBREAK, nwHeadFmt.BR)
if heading == self.EDIT_TITLE: if heading == self.EDIT_TITLE:
self.fmtPart.setText(text) self.fmtPart.setText(text)
self._build.setValue("headings.fmtPart", text) self._build.setValue("headings.fmtPart", value)
elif heading == self.EDIT_CHAPTER: elif heading == self.EDIT_CHAPTER:
self.fmtChapter.setText(text) self.fmtChapter.setText(text)
self._build.setValue("headings.fmtChapter", text) self._build.setValue("headings.fmtChapter", value)
elif heading == self.EDIT_UNNUM: elif heading == self.EDIT_UNNUM:
self.fmtUnnumbered.setText(text) self.fmtUnnumbered.setText(text)
self._build.setValue("headings.fmtUnnumbered", text) self._build.setValue("headings.fmtUnnumbered", value)
elif heading == self.EDIT_SCENE: elif heading == self.EDIT_SCENE:
self.fmtScene.setText(text) self.fmtScene.setText(text)
self._build.setValue("headings.fmtScene", text) self._build.setValue("headings.fmtScene", value)
elif heading == self.EDIT_HSCENE: elif heading == self.EDIT_HSCENE:
self.fmtAScene.setText(text) self.fmtAScene.setText(text)
self._build.setValue("headings.fmtAltScene", text) self._build.setValue("headings.fmtAltScene", value)
elif heading == self.EDIT_SECTION: elif heading == self.EDIT_SECTION:
self.fmtSection.setText(text) self.fmtSection.setText(text)
self._build.setValue("headings.fmtSection", text) self._build.setValue("headings.fmtSection", value)
else: else:
return return
+1
View File
@@ -52,6 +52,7 @@ QtVAlignSuper = QTextCharFormat.VerticalAlignment.AlignSuperScript
QtPageBreakBefore = QTextFormat.PageBreakFlag.PageBreak_AlwaysBefore QtPageBreakBefore = QTextFormat.PageBreakFlag.PageBreak_AlwaysBefore
QtPageBreakAfter = QTextFormat.PageBreakFlag.PageBreak_AlwaysAfter QtPageBreakAfter = QTextFormat.PageBreakFlag.PageBreak_AlwaysAfter
QtPageBreakAuto = QTextFormat.PageBreakFlag.PageBreak_Auto
QtPropLineHeight = 1 # QTextBlockFormat.LineHeightTypes.ProportionalHeight QtPropLineHeight = 1 # QTextBlockFormat.LineHeightTypes.ProportionalHeight
+8 -8
View File
@@ -1659,7 +1659,7 @@ def testFmtToken_ProcessHeaders(mockGUI):
# H2: Chapter Word Number # H2: Chapter Word Number
tokens._text = "## Chapter\n" tokens._text = "## Chapter\n"
tokens.setChapterFormat(f"Chapter {nwHeadFmt.CH_WORD}") tokens.setChapterFormat(f"Chapter {nwHeadFmt.CH_WORD}")
tokens._hFormatter._chCount = 0 tokens._hFormatter._chapter = 0
tokens.tokenizeText() tokens.tokenizeText()
assert tokens._blocks == [ assert tokens._blocks == [
(BlockTyp.HEAD1, TM1, "Chapter One", [], BlockFmt.PBB), (BlockTyp.HEAD1, TM1, "Chapter One", [], BlockFmt.PBB),
@@ -1733,8 +1733,8 @@ def testFmtToken_ProcessHeaders(mockGUI):
# H3: Scene w/Absolute Number # H3: Scene w/Absolute Number
tokens._text = "### A Scene\n" tokens._text = "### A Scene\n"
tokens.setSceneFormat(f"Scene {nwHeadFmt.SC_ABS}", False) tokens.setSceneFormat(f"Scene {nwHeadFmt.SC_ABS}", False)
tokens._hFormatter._scAbsCount = 0 tokens._hFormatter._scene = 0
tokens._hFormatter._scChCount = 0 tokens._hFormatter._absolute = 0
tokens.tokenizeText() tokens.tokenizeText()
assert tokens._blocks == [ assert tokens._blocks == [
(BlockTyp.HEAD2, TM1, "Scene 1", [], BlockFmt.NONE), (BlockTyp.HEAD2, TM1, "Scene 1", [], BlockFmt.NONE),
@@ -1743,8 +1743,8 @@ def testFmtToken_ProcessHeaders(mockGUI):
# H3: Scene w/Chapter Number # H3: Scene w/Chapter Number
tokens._text = "### A Scene\n" tokens._text = "### A Scene\n"
tokens.setSceneFormat(f"Scene {nwHeadFmt.CH_NUM}.{nwHeadFmt.SC_NUM}", False) tokens.setSceneFormat(f"Scene {nwHeadFmt.CH_NUM}.{nwHeadFmt.SC_NUM}", False)
tokens._hFormatter._scAbsCount = 0 tokens._hFormatter._scene = 1
tokens._hFormatter._scChCount = 1 tokens._hFormatter._absolute = 0
tokens.tokenizeText() tokens.tokenizeText()
assert tokens._blocks == [ assert tokens._blocks == [
(BlockTyp.HEAD2, TM1, "Scene 3.2", [], BlockFmt.NONE), (BlockTyp.HEAD2, TM1, "Scene 3.2", [], BlockFmt.NONE),
@@ -2549,9 +2549,9 @@ def testFmtToken_HeadingFormatter(fncPath, mockGUI, mockRnd):
# Special Formats # Special Formats
# =============== # ===============
formatter._chCount = 2 formatter._chapter = 2
formatter._scChCount = 3 formatter._scene = 3
formatter._scAbsCount = 8 formatter._absolute = 8
# Chapter Number Word # Chapter Number Word
cFormat = f"Chapter {nwHeadFmt.CH_WORD}, Scene {nwHeadFmt.SC_NUM} - {nwHeadFmt.TITLE}" cFormat = f"Chapter {nwHeadFmt.CH_WORD}, Scene {nwHeadFmt.SC_NUM} - {nwHeadFmt.TITLE}"
+28 -6
View File
@@ -25,14 +25,15 @@ import pytest
from PyQt6.QtGui import QFont, QTextBlock, QTextCharFormat, QTextCursor from PyQt6.QtGui import QFont, QTextBlock, QTextCharFormat, QTextCursor
from novelwriter import CONFIG from novelwriter import CONFIG
from novelwriter.constants import nwUnicode from novelwriter.constants import nwHeadFmt, nwUnicode
from novelwriter.core.project import NWProject from novelwriter.core.project import NWProject
from novelwriter.enum import nwComment from novelwriter.enum import nwComment
from novelwriter.formats.shared import BlockFmt, BlockTyp, TextDocumentTheme from novelwriter.formats.shared import BlockFmt, BlockTyp, TextDocumentTheme
from novelwriter.formats.toqdoc import ToQTextDocument from novelwriter.formats.toqdoc import ToQTextDocument
from novelwriter.types import ( from novelwriter.types import (
QtAlignAbsolute, QtAlignCenter, QtAlignJustify, QtAlignLeft, QtAlignRight, QtAlignAbsolute, QtAlignCenter, QtAlignJustify, QtAlignLeft, QtAlignRight,
QtPageBreakAfter, QtTransparent, QtVAlignNormal, QtVAlignSub, QtVAlignSuper QtPageBreakAfter, QtPageBreakAuto, QtPageBreakBefore, QtTransparent,
QtVAlignNormal, QtVAlignSub, QtVAlignSuper
) )
THEME = TextDocumentTheme() THEME = TextDocumentTheme()
@@ -54,6 +55,11 @@ def testFmtToQTextDocument_ConvertHeaders(mockGUI):
doc._isNovel = True doc._isNovel = True
doc._isFirst = True doc._isFirst = True
# Add a line break in chapter header format, see #2415
doc.setChapterFormat(f"{nwHeadFmt.CH_NUM}{nwHeadFmt.BR}{nwHeadFmt.TITLE}")
# Populate
doc._text = ( doc._text = (
"#! Title\n" "#! Title\n"
"# Partition\n" "# Partition\n"
@@ -63,12 +69,13 @@ def testFmtToQTextDocument_ConvertHeaders(mockGUI):
) )
doc.tokenizeText() doc.tokenizeText()
doc.doConvert() doc.doConvert()
assert doc.document.blockCount() == 5 assert doc.document.blockCount() == 6
# Title # Title
block = doc.document.findBlockByNumber(0) block = doc.document.findBlockByNumber(0)
assert block.text() == "Title" assert block.text() == "Title"
bFmt = block.blockFormat() bFmt = block.blockFormat()
assert bFmt.pageBreakPolicy() == QtPageBreakAuto # Expected on first title
assert bFmt.topMargin() == doc._mHead[BlockTyp.TITLE][0] assert bFmt.topMargin() == doc._mHead[BlockTyp.TITLE][0]
assert bFmt.bottomMargin() == doc._mHead[BlockTyp.TITLE][1] assert bFmt.bottomMargin() == doc._mHead[BlockTyp.TITLE][1]
cFmt = charFmtInBlock(block, 1) cFmt = charFmtInBlock(block, 1)
@@ -87,10 +94,23 @@ def testFmtToQTextDocument_ConvertHeaders(mockGUI):
assert cFmt.fontPointSize() == doc._sHead[BlockTyp.PART] assert cFmt.fontPointSize() == doc._sHead[BlockTyp.PART]
assert cFmt.foreground().color() == THEME.head assert cFmt.foreground().color() == THEME.head
# Chapter # Chapter, Line 1
block = doc.document.findBlockByNumber(2) block = doc.document.findBlockByNumber(2)
assert block.text() == "1"
bFmt = block.blockFormat()
assert bFmt.pageBreakPolicy() == QtPageBreakBefore
assert bFmt.topMargin() == doc._mHead[BlockTyp.HEAD1][0]
assert bFmt.bottomMargin() == doc._mHead[BlockTyp.HEAD1][1]
cFmt = charFmtInBlock(block, 1)
assert cFmt.fontWeight() == QFont.Weight.Bold
assert cFmt.fontPointSize() == doc._sHead[BlockTyp.HEAD1]
assert cFmt.foreground().color() == THEME.head
# Chapter, Line 2
block = doc.document.findBlockByNumber(3)
assert block.text() == "Chapter" assert block.text() == "Chapter"
bFmt = block.blockFormat() bFmt = block.blockFormat()
assert bFmt.pageBreakPolicy() == QtPageBreakAuto # Important! See #2415
assert bFmt.topMargin() == doc._mHead[BlockTyp.HEAD1][0] assert bFmt.topMargin() == doc._mHead[BlockTyp.HEAD1][0]
assert bFmt.bottomMargin() == doc._mHead[BlockTyp.HEAD1][1] assert bFmt.bottomMargin() == doc._mHead[BlockTyp.HEAD1][1]
cFmt = charFmtInBlock(block, 1) cFmt = charFmtInBlock(block, 1)
@@ -99,9 +119,10 @@ def testFmtToQTextDocument_ConvertHeaders(mockGUI):
assert cFmt.foreground().color() == THEME.head assert cFmt.foreground().color() == THEME.head
# Scene # Scene
block = doc.document.findBlockByNumber(3) block = doc.document.findBlockByNumber(4)
assert block.text() == "Scene" assert block.text() == "Scene"
bFmt = block.blockFormat() bFmt = block.blockFormat()
assert bFmt.pageBreakPolicy() == QtPageBreakAuto
assert bFmt.topMargin() == doc._mHead[BlockTyp.HEAD2][0] assert bFmt.topMargin() == doc._mHead[BlockTyp.HEAD2][0]
assert bFmt.bottomMargin() == doc._mHead[BlockTyp.HEAD2][1] assert bFmt.bottomMargin() == doc._mHead[BlockTyp.HEAD2][1]
cFmt = charFmtInBlock(block, 1) cFmt = charFmtInBlock(block, 1)
@@ -110,9 +131,10 @@ def testFmtToQTextDocument_ConvertHeaders(mockGUI):
assert cFmt.foreground().color() == THEME.head assert cFmt.foreground().color() == THEME.head
# Section # Section
block = doc.document.findBlockByNumber(4) block = doc.document.findBlockByNumber(5)
assert block.text() == "Section" assert block.text() == "Section"
bFmt = block.blockFormat() bFmt = block.blockFormat()
assert bFmt.pageBreakPolicy() == QtPageBreakAuto
assert bFmt.topMargin() == doc._mHead[BlockTyp.HEAD3][0] assert bFmt.topMargin() == doc._mHead[BlockTyp.HEAD3][0]
assert bFmt.bottomMargin() == doc._mHead[BlockTyp.HEAD3][1] assert bFmt.bottomMargin() == doc._mHead[BlockTyp.HEAD3][1]
cFmt = charFmtInBlock(block, 1) cFmt = charFmtInBlock(block, 1)