Add hard scene break format (#1753)
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 70 KiB |
@@ -75,6 +75,10 @@ Organising Your Text
|
||||
Keep in mind that this is not what the section heading is intended for, so the app will not
|
||||
understand the section heading as a scene, but it will be formatted correctly in the manuscript.
|
||||
|
||||
.. versionadded:: 2.4
|
||||
You can now distinguish between soft and hard scene breaks with a modified scene header. See
|
||||
:ref:`a_manuscript_settings_head_hard` for more details.
|
||||
|
||||
|
||||
Other Tools
|
||||
===========
|
||||
|
||||
@@ -63,6 +63,8 @@ In the figure, the green arrow icon and the blue pin icon indicates which docume
|
||||
and the red forbidden icon indicates that a document is explicitly excluded.
|
||||
|
||||
|
||||
.. _a_manuscript_settings_head:
|
||||
|
||||
Formatting Headings
|
||||
-------------------
|
||||
|
||||
@@ -86,6 +88,7 @@ Any text you add that isn't highlighted in colours will remain in your formatted
|
||||
You can preview the result of these format strings by clicking :guilabel:`Apply`, and then clicking
|
||||
:guilabel:`Preview` in the :guilabel:`Manuscript Build` tool main window.
|
||||
|
||||
|
||||
Scene Separators
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -99,6 +102,19 @@ the desired separator text as the format. If the format is any piece of static t
|
||||
be treated as a separator.
|
||||
|
||||
|
||||
.. _a_manuscript_settings_head_hard:
|
||||
|
||||
Hard and Soft Scenes
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you wish to distinguish between so-called soft and hard scene breaks, where a hard scene break
|
||||
is understood as a scene break that changes point-of-view character, you can use the modified scene
|
||||
heading format in your text. You can then give these headings a different formatting in the
|
||||
:guilabel:`Headings` settings.
|
||||
|
||||
See :ref:`a_fmt_head` for more info on how to format headings in your text.
|
||||
|
||||
|
||||
Output Settings
|
||||
---------------
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ correctly to produce the intended result. See :ref:`a_struct_heads` for more det
|
||||
Heading level four. For novel documents, the level indicates the start of a new section. Section
|
||||
titles can be replaced by separators or ignored completely when building the manuscript.
|
||||
|
||||
For headings level one and two, adding a ``!`` modifies its meaning:
|
||||
For headings level one through three, adding a ``!`` modifies its meaning:
|
||||
|
||||
``#! Title Text``
|
||||
This tells the build tool that the level one heading is intended to be used for the novel's or
|
||||
@@ -81,6 +81,11 @@ For headings level one and two, adding a ``!`` modifies its meaning:
|
||||
chapter numbers are being used. Such titles are useful for a prologue for instance. See
|
||||
:ref:`a_struct_heads_unnum` for more details.
|
||||
|
||||
``###! Title Text``
|
||||
This is an alternative scene heading that can be formatted differently in the
|
||||
:guilabel:`Manuscript Build` tool. It is intended for separating "soft" and "hard" scene breaks.
|
||||
Otherwise, it behaves identically to a regular scene heading.
|
||||
|
||||
.. note::
|
||||
The space after the ``#`` or ``!`` character is mandatory. The syntax highlighter will change
|
||||
colour and font size when the heading is correctly formatted.
|
||||
|
||||
@@ -56,8 +56,10 @@ SETTINGS_TEMPLATE = {
|
||||
"headings.fmtChapter": (str, nwHeadFmt.TITLE),
|
||||
"headings.fmtUnnumbered": (str, nwHeadFmt.TITLE),
|
||||
"headings.fmtScene": (str, "* * *"),
|
||||
"headings.fmtHardScene": (str, ""),
|
||||
"headings.fmtSection": (str, ""),
|
||||
"headings.hideScene": (bool, False),
|
||||
"headings.hideHardScene": (bool, False),
|
||||
"headings.hideSection": (bool, True),
|
||||
"headings.centerTitle": (bool, True),
|
||||
"headings.centerChapter": (bool, False),
|
||||
@@ -100,13 +102,15 @@ SETTINGS_LABELS = {
|
||||
"filter.includeInactive": QT_TRANSLATE_NOOP("Builds", "Inactive Documents"),
|
||||
|
||||
"headings": QT_TRANSLATE_NOOP("Builds", "Headings"),
|
||||
"headings.fmtTitle": QT_TRANSLATE_NOOP("Builds", "Title Headings"),
|
||||
"headings.fmtChapter": QT_TRANSLATE_NOOP("Builds", "Chapter Headings"),
|
||||
"headings.fmtUnnumbered": QT_TRANSLATE_NOOP("Builds", "Unnumbered Headings"),
|
||||
"headings.fmtScene": QT_TRANSLATE_NOOP("Builds", "Scene Headings"),
|
||||
"headings.fmtSection": QT_TRANSLATE_NOOP("Builds", "Section Headings"),
|
||||
"headings.hideScene": QT_TRANSLATE_NOOP("Builds", "Hide Scene Headings"),
|
||||
"headings.hideSection": QT_TRANSLATE_NOOP("Builds", "Hide Section Headings"),
|
||||
"headings.fmtTitle": QT_TRANSLATE_NOOP("Builds", "Partition Format"),
|
||||
"headings.fmtChapter": QT_TRANSLATE_NOOP("Builds", "Chapter Format"),
|
||||
"headings.fmtUnnumbered": QT_TRANSLATE_NOOP("Builds", "Unnumbered Format"),
|
||||
"headings.fmtScene": QT_TRANSLATE_NOOP("Builds", "Scene Format"),
|
||||
"headings.fmtHardScene": QT_TRANSLATE_NOOP("Builds", "Hard Scene Format"),
|
||||
"headings.fmtSection": QT_TRANSLATE_NOOP("Builds", "Section Format"),
|
||||
"headings.hideScene": QT_TRANSLATE_NOOP("Builds", "Hide Scene Breaks"),
|
||||
"headings.hideHardScene": QT_TRANSLATE_NOOP("Builds", "Hide Hard Scene Breaks"),
|
||||
"headings.hideSection": QT_TRANSLATE_NOOP("Builds", "Hide Section Breaks"),
|
||||
|
||||
"text.grpContent": QT_TRANSLATE_NOOP("Builds", "Text Content"),
|
||||
"text.includeSynopsis": QT_TRANSLATE_NOOP("Builds", "Include Synopsis"),
|
||||
|
||||
@@ -282,6 +282,10 @@ class NWBuildDocument:
|
||||
self._build.getStr("headings.fmtScene"),
|
||||
self._build.getBool("headings.hideScene")
|
||||
)
|
||||
bldObj.setHardSceneFormat(
|
||||
self._build.getStr("headings.fmtHardScene"),
|
||||
self._build.getBool("headings.hideHardScene")
|
||||
)
|
||||
bldObj.setSectionFormat(
|
||||
self._build.getStr("headings.fmtSection"),
|
||||
self._build.getBool("headings.hideSection")
|
||||
|
||||
@@ -396,6 +396,8 @@ class NWIndex:
|
||||
return "H1", line[3:].strip()
|
||||
elif line.startswith("##! "):
|
||||
return "H2", line[4:].strip()
|
||||
elif line.startswith("###! "):
|
||||
return "H3", line[5:].strip()
|
||||
return "H0", ""
|
||||
|
||||
def _indexWordCounts(self, tHandle: str, text: str, sTitle: str) -> None:
|
||||
|
||||
@@ -156,9 +156,11 @@ class Tokenizer(ABC):
|
||||
self._fmtChapter = nwHeadFmt.TITLE # Formatting for numbered chapters
|
||||
self._fmtUnNum = nwHeadFmt.TITLE # Formatting for unnumbered chapters
|
||||
self._fmtScene = nwHeadFmt.TITLE # Formatting for scenes
|
||||
self._fmtHScene = nwHeadFmt.TITLE # Formatting for hard scenes
|
||||
self._fmtSection = nwHeadFmt.TITLE # Formatting for sections
|
||||
|
||||
self._hideScene = False # Do not include scene headings
|
||||
self._hideHScene = False # Do not include hard scene headings
|
||||
self._hideSection = False # Do not include section headings
|
||||
|
||||
self._linkHeaders = False # Add an anchor before headings
|
||||
@@ -254,6 +256,12 @@ class Tokenizer(ABC):
|
||||
self._hideScene = hide
|
||||
return
|
||||
|
||||
def setHardSceneFormat(self, hFormat: str, hide: bool) -> None:
|
||||
"""Set the hard scene format pattern and hidden status."""
|
||||
self._fmtHScene = hFormat.strip()
|
||||
self._hideHScene = hide
|
||||
return
|
||||
|
||||
def setSectionFormat(self, hFormat: str, hide: bool) -> None:
|
||||
"""Set the section format pattern and hidden status."""
|
||||
self._fmtSection = hFormat.strip()
|
||||
@@ -484,7 +492,7 @@ class Tokenizer(ABC):
|
||||
# Check Line Format
|
||||
# =================
|
||||
|
||||
if aLine[0] == "[":
|
||||
if aLine.startswith("["):
|
||||
# Special Formats
|
||||
# ===============
|
||||
# Parse special formatting line. This must be a separate if
|
||||
@@ -513,13 +521,13 @@ class Tokenizer(ABC):
|
||||
]
|
||||
continue
|
||||
|
||||
if aLine[0] == "%":
|
||||
if aLine.startswith("%"):
|
||||
# Comments
|
||||
# ========
|
||||
# All style comments are processed and the exact type exact
|
||||
# style extracted. Ignored comments on the '%~' format are
|
||||
# skipped completely.
|
||||
if aLine[1] == "~":
|
||||
if aLine.startswith("%~"):
|
||||
continue
|
||||
|
||||
cStyle, cText, _ = processComment(aLine)
|
||||
@@ -542,7 +550,7 @@ class Tokenizer(ABC):
|
||||
if self._doComments and self._keepMarkdown:
|
||||
tmpMarkdown.append(f"{aLine}\n")
|
||||
|
||||
elif aLine[0] == "@":
|
||||
elif aLine.startswith("@"):
|
||||
# Keywords
|
||||
# ========
|
||||
# Only valid keyword lines are parsed, and any ignored keywords
|
||||
@@ -556,56 +564,70 @@ class Tokenizer(ABC):
|
||||
if self._doKeywords and self._keepMarkdown:
|
||||
tmpMarkdown.append(f"{aLine}\n")
|
||||
|
||||
elif aLine[:2] == "# ":
|
||||
# Partition Headings
|
||||
# ==================
|
||||
elif aLine.startswith(("# ", "#! ")):
|
||||
# Title or Partition Headings
|
||||
# ===========================
|
||||
# Main titles are allowed in any document, and they are always
|
||||
# centred and start on a new page. For novel documents, we also
|
||||
# reset all counters when such a title is encountered.
|
||||
# Partition headings are only formatted in novel documents, and
|
||||
# otherwise unchanged. Scene separators are disabled
|
||||
# immediately after partitions, and scene numbers are reset.
|
||||
isPlain = aLine.startswith("# ")
|
||||
|
||||
nHead += 1
|
||||
tText = aLine[2:].strip()
|
||||
tStyle = self.A_NONE
|
||||
tType = self.T_HEAD1 if isPlain else self.T_TITLE
|
||||
tStyle = self.A_NONE if isPlain else (self.A_PBB | self.A_CENTRE)
|
||||
if self._isNovel:
|
||||
tText = self._hFormatter.apply(self._fmtTitle, tText, nHead)
|
||||
tStyle = self._titleStyle
|
||||
if isPlain:
|
||||
tText = self._hFormatter.apply(self._fmtTitle, tText, nHead)
|
||||
tStyle = self._titleStyle
|
||||
self._hFormatter.resetScene()
|
||||
else:
|
||||
self._hFormatter.resetAll()
|
||||
self._noSep = True
|
||||
self._hFormatter.resetScene()
|
||||
|
||||
self._tokens.append((
|
||||
self.T_HEAD1, nHead, tText, [], tStyle
|
||||
tType, nHead, tText, [], tStyle
|
||||
))
|
||||
if self._keepMarkdown:
|
||||
tmpMarkdown.append(f"{aLine}\n")
|
||||
|
||||
elif aLine[:3] == "## ":
|
||||
# Chapter Headings
|
||||
# ================
|
||||
elif aLine.startswith(("## ", "##! ")):
|
||||
# (Unnumbered) Chapter Headings
|
||||
# =============================
|
||||
# Chapter headings are only formatted in novel documents, and
|
||||
# otherwise unchanged. Chapter numbers are bumped before the
|
||||
# heading is formatted. Scene separators are disabled
|
||||
# immediately after chapter headings, and scene numbers are
|
||||
# reset.
|
||||
# reset. Unnumbered chapters are only meaningful in Novel docs,
|
||||
# so if we're in a note, we keep them as level 2 headings.
|
||||
isPlain = aLine.startswith("## ")
|
||||
|
||||
nHead += 1
|
||||
tText = aLine[3:].strip()
|
||||
tType = self.T_HEAD2
|
||||
tStyle = self.A_NONE
|
||||
tFormat = self._fmtChapter if isPlain else self._fmtUnNum
|
||||
if self._isNovel:
|
||||
self._hFormatter.incChapter()
|
||||
tText = self._hFormatter.apply(self._fmtChapter, tText, nHead)
|
||||
if isPlain:
|
||||
self._hFormatter.incChapter()
|
||||
tText = self._hFormatter.apply(tFormat, tText, nHead)
|
||||
tType = self.T_HEAD2 if isPlain else self.T_UNNUM
|
||||
tStyle = self._chapterStyle
|
||||
self._noSep = True
|
||||
self._hFormatter.resetScene()
|
||||
|
||||
self._tokens.append((
|
||||
self.T_HEAD2, nHead, tText, [], tStyle
|
||||
tType, nHead, tText, [], tStyle
|
||||
))
|
||||
if self._keepMarkdown:
|
||||
tmpMarkdown.append(f"{aLine}\n")
|
||||
|
||||
elif aLine[:4] == "### ":
|
||||
# Scene Headings
|
||||
# ==============
|
||||
elif aLine.startswith(("### ", "###! ")):
|
||||
# (Hard) Scene Headings
|
||||
# =====================
|
||||
# Scene headings in novel documents are treated as centred
|
||||
# separators if the formatting does not change the text. If the
|
||||
# format is empty, the scene can be hidden or a blank paragraph
|
||||
@@ -614,19 +636,22 @@ class Tokenizer(ABC):
|
||||
# separators immediately after other titles. Scene numbers are
|
||||
# always incremented before formatting. For notes, the heading
|
||||
# is unchanged.
|
||||
isPlain = aLine.startswith("### ")
|
||||
|
||||
nHead += 1
|
||||
tText = aLine[4:].strip()
|
||||
tType = self.T_HEAD3
|
||||
tStyle = self.A_NONE
|
||||
sHide = self._hideScene if isPlain else self._hideHScene
|
||||
tFormat = self._fmtScene if isPlain else self._fmtHScene
|
||||
if self._isNovel:
|
||||
self._hFormatter.incScene()
|
||||
tText = self._hFormatter.apply(self._fmtScene, tText, nHead)
|
||||
tText = self._hFormatter.apply(tFormat, tText, nHead)
|
||||
tStyle = self._sceneStyle
|
||||
if tText == "":
|
||||
tType = self.T_EMPTY if self._noSep or self._hideScene else self.T_SKIP
|
||||
tType = self.T_EMPTY if self._noSep or sHide else self.T_SKIP
|
||||
tStyle = self.A_NONE
|
||||
elif tText == self._fmtScene:
|
||||
elif tText == tFormat:
|
||||
tText = "" if self._noSep else tText
|
||||
tType = self.T_EMPTY if self._noSep else self.T_SEP
|
||||
tStyle = self.A_NONE if self._noSep else self.A_CENTRE
|
||||
@@ -638,7 +663,7 @@ class Tokenizer(ABC):
|
||||
if self._keepMarkdown:
|
||||
tmpMarkdown.append(f"{aLine}\n")
|
||||
|
||||
elif aLine[:5] == "#### ":
|
||||
elif aLine.startswith("#### "):
|
||||
# Section Headings
|
||||
# =================
|
||||
# Section headings in novel docs are treated as centred
|
||||
@@ -664,46 +689,6 @@ class Tokenizer(ABC):
|
||||
if self._keepMarkdown:
|
||||
tmpMarkdown.append(f"{aLine}\n")
|
||||
|
||||
elif aLine[:3] == "#! ":
|
||||
# Main Title
|
||||
# ==========
|
||||
# Main titles are allowed in any document, and they are always
|
||||
# centred and start on a new page. For novel documents, we also
|
||||
# reset all counters when such a title is encountered.
|
||||
|
||||
nHead += 1
|
||||
self._tokens.append((
|
||||
self.T_TITLE, nHead, aLine[3:].strip(), [], self.A_PBB | self.A_CENTRE
|
||||
))
|
||||
if self._isNovel:
|
||||
self._noSep = True
|
||||
self._hFormatter.resetAll()
|
||||
if self._keepMarkdown:
|
||||
tmpMarkdown.append(f"{aLine}\n")
|
||||
|
||||
elif aLine[:4] == "##! ":
|
||||
# Unnumbered Chapter Headings
|
||||
# ===========================
|
||||
# Unnumbered chapters are only meaningful in Novel docs, so if
|
||||
# we're in a note, we convert them to a plain level 2 heading.
|
||||
|
||||
nHead += 1
|
||||
tText = aLine[4:].strip()
|
||||
tType = self.T_HEAD2
|
||||
tStyle = self.A_NONE
|
||||
if self._isNovel:
|
||||
tText = self._hFormatter.apply(self._fmtUnNum, tText, nHead)
|
||||
tType = self.T_UNNUM
|
||||
tStyle = self._chapterStyle
|
||||
self._noSep = True
|
||||
self._hFormatter.resetScene()
|
||||
|
||||
self._tokens.append((
|
||||
tType, nHead, tText, [], tStyle
|
||||
))
|
||||
if self._keepMarkdown:
|
||||
tmpMarkdown.append(f"{aLine}\n")
|
||||
|
||||
else:
|
||||
# Text Lines
|
||||
# ==========
|
||||
|
||||
+16
-15
@@ -112,21 +112,22 @@ class nwDocAction(Enum):
|
||||
BLOCK_TXT = 19
|
||||
BLOCK_TTL = 20
|
||||
BLOCK_UNN = 21
|
||||
REPL_SNG = 22
|
||||
REPL_DBL = 23
|
||||
RM_BREAKS = 24
|
||||
ALIGN_L = 25
|
||||
ALIGN_C = 26
|
||||
ALIGN_R = 27
|
||||
INDENT_L = 28
|
||||
INDENT_R = 29
|
||||
SC_ITALIC = 30
|
||||
SC_BOLD = 31
|
||||
SC_STRIKE = 32
|
||||
SC_ULINE = 33
|
||||
SC_MARK = 34
|
||||
SC_SUP = 35
|
||||
SC_SUB = 36
|
||||
BLOCK_HSC = 22
|
||||
REPL_SNG = 23
|
||||
REPL_DBL = 24
|
||||
RM_BREAKS = 25
|
||||
ALIGN_L = 26
|
||||
ALIGN_C = 27
|
||||
ALIGN_R = 28
|
||||
INDENT_L = 29
|
||||
INDENT_R = 30
|
||||
SC_ITALIC = 31
|
||||
SC_BOLD = 32
|
||||
SC_STRIKE = 33
|
||||
SC_ULINE = 34
|
||||
SC_MARK = 35
|
||||
SC_SUP = 36
|
||||
SC_SUB = 37
|
||||
|
||||
# END Enum nwDocAction
|
||||
|
||||
|
||||
@@ -744,6 +744,8 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
self._formatBlock(nwDocAction.BLOCK_TTL)
|
||||
elif action == nwDocAction.BLOCK_UNN:
|
||||
self._formatBlock(nwDocAction.BLOCK_UNN)
|
||||
elif action == nwDocAction.BLOCK_HSC:
|
||||
self._formatBlock(nwDocAction.BLOCK_HSC)
|
||||
elif action == nwDocAction.REPL_SNG:
|
||||
self._replaceQuotes("'", self._typSQuoteO, self._typSQuoteC)
|
||||
elif action == nwDocAction.REPL_DBL:
|
||||
@@ -1651,6 +1653,9 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
elif text.startswith("##! "):
|
||||
temp = text[4:]
|
||||
offset = 4
|
||||
elif text.startswith("###! "):
|
||||
temp = text[5:]
|
||||
offset = 5
|
||||
elif text.startswith(">> "):
|
||||
temp = text[3:]
|
||||
offset = 3
|
||||
@@ -1702,6 +1707,9 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
elif action == nwDocAction.BLOCK_UNN:
|
||||
text = f"##! {temp}"
|
||||
offset -= 4
|
||||
elif action == nwDocAction.BLOCK_HSC:
|
||||
text = f"###! {temp}"
|
||||
offset -= 5
|
||||
elif action == nwDocAction.ALIGN_L:
|
||||
text = f"{temp} <<"
|
||||
elif action == nwDocAction.ALIGN_C:
|
||||
|
||||
@@ -300,7 +300,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
||||
# so we force a return here
|
||||
return
|
||||
|
||||
elif text.startswith(("# ", "#! ", "## ", "##! ", "### ", "#### ")):
|
||||
elif text.startswith(("# ", "#! ", "## ", "##! ", "### ", "###! ", "#### ")):
|
||||
self.setCurrentBlockState(self.BLOCK_TITLE)
|
||||
|
||||
if text.startswith("# "): # Heading 1
|
||||
@@ -327,6 +327,10 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
||||
self.setFormat(0, 3, self._hStyles["head2h"])
|
||||
self.setFormat(3, len(text), self._hStyles["header2"])
|
||||
|
||||
elif text.startswith("###! "): # Hard Scene
|
||||
self.setFormat(0, 4, self._hStyles["head3h"])
|
||||
self.setFormat(4, len(text), self._hStyles["header3"])
|
||||
|
||||
elif text.startswith("%"): # Comments
|
||||
self.setCurrentBlockState(self.BLOCK_TEXT)
|
||||
cStyle, _, cPos = processComment(text)
|
||||
|
||||
@@ -735,6 +735,12 @@ class GuiMainMenu(QMenuBar):
|
||||
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_UNN)
|
||||
)
|
||||
|
||||
# Format > Hard Scene
|
||||
self.aFmtHardSc = self.fmtMenu.addAction(self.tr("Hard Scene"))
|
||||
self.aFmtHardSc.triggered.connect(
|
||||
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_HSC)
|
||||
)
|
||||
|
||||
# Format > Separator
|
||||
self.fmtMenu.addSeparator()
|
||||
|
||||
|
||||
@@ -106,6 +106,9 @@ def standardCounter(text: str) -> tuple[int, int, int]:
|
||||
elif line[:4] == "##! ":
|
||||
line = line[4:]
|
||||
countPara = False
|
||||
elif line[:5] == "###! ":
|
||||
line = line[5:]
|
||||
countPara = False
|
||||
|
||||
wCount += len(line.split())
|
||||
cCount += len(line)
|
||||
|
||||
@@ -610,16 +610,15 @@ class _DetailsWidget(QWidget):
|
||||
item.setText(0, build.getLabel("headings"))
|
||||
item.setText(1, "")
|
||||
self.listView.addTopLevelItem(item)
|
||||
entries = [
|
||||
for key in [
|
||||
"headings.fmtTitle", "headings.fmtChapter", "headings.fmtUnnumbered",
|
||||
"headings.fmtScene", "headings.fmtSection"
|
||||
]
|
||||
for key in entries:
|
||||
"headings.fmtScene", "headings.fmtHardScene", "headings.fmtSection"
|
||||
]:
|
||||
sub = QTreeWidgetItem()
|
||||
sub.setText(0, build.getLabel(key))
|
||||
sub.setText(1, hFmt.apply(build.getStr(key), title, 0))
|
||||
item.addChild(sub)
|
||||
for key in ["headings.hideScene", "headings.hideSection"]:
|
||||
for key in ["headings.hideScene", "headings.hideHardScene", "headings.hideSection"]:
|
||||
sub = QTreeWidgetItem()
|
||||
sub.setText(0, build.getLabel(key))
|
||||
sub.setIcon(1, on if build.getBool(key) else off)
|
||||
@@ -630,11 +629,10 @@ class _DetailsWidget(QWidget):
|
||||
item.setText(0, build.getLabel("text.grpContent"))
|
||||
item.setText(1, "")
|
||||
self.listView.addTopLevelItem(item)
|
||||
entries = [
|
||||
for key in [
|
||||
"text.includeSynopsis", "text.includeComments",
|
||||
"text.includeKeywords", "text.includeBodyText",
|
||||
]
|
||||
for key in entries:
|
||||
]:
|
||||
sub = QTreeWidgetItem()
|
||||
sub.setText(0, build.getLabel(key))
|
||||
sub.setIcon(1, on if build.getBool(key) else off)
|
||||
|
||||
@@ -584,7 +584,8 @@ class _HeadingsTab(NScrollablePage):
|
||||
EDIT_CHAPTER = 2
|
||||
EDIT_UNNUM = 3
|
||||
EDIT_SCENE = 4
|
||||
EDIT_SECTION = 5
|
||||
EDIT_HSCENE = 5
|
||||
EDIT_SECTION = 6
|
||||
|
||||
def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings) -> None:
|
||||
super().__init__(parent=buildMain)
|
||||
@@ -603,7 +604,7 @@ class _HeadingsTab(NScrollablePage):
|
||||
self.formatBox.setHorizontalSpacing(vSp)
|
||||
|
||||
# Title Heading
|
||||
self.lblTitle = QLabel(self._build.getLabel("headings.fmtTitle"))
|
||||
self.lblTitle = QLabel(self._build.getLabel("headings.fmtTitle"), self)
|
||||
self.fmtTitle = QLineEdit("", self)
|
||||
self.fmtTitle.setReadOnly(True)
|
||||
self.btnTitle = QToolButton(self)
|
||||
@@ -619,7 +620,7 @@ class _HeadingsTab(NScrollablePage):
|
||||
self.formatBox.addLayout(wrapTitle, 0, 1)
|
||||
|
||||
# Chapter Heading
|
||||
self.lblChapter = QLabel(self._build.getLabel("headings.fmtChapter"))
|
||||
self.lblChapter = QLabel(self._build.getLabel("headings.fmtChapter"), self)
|
||||
self.fmtChapter = QLineEdit("", self)
|
||||
self.fmtChapter.setReadOnly(True)
|
||||
self.btnChapter = QToolButton(self)
|
||||
@@ -635,7 +636,7 @@ class _HeadingsTab(NScrollablePage):
|
||||
self.formatBox.addLayout(wrapChapter, 1, 1)
|
||||
|
||||
# Unnumbered Chapter Heading
|
||||
self.lblUnnumbered = QLabel(self._build.getLabel("headings.fmtUnnumbered"))
|
||||
self.lblUnnumbered = QLabel(self._build.getLabel("headings.fmtUnnumbered"), self)
|
||||
self.fmtUnnumbered = QLineEdit("", self)
|
||||
self.fmtUnnumbered.setReadOnly(True)
|
||||
self.btnUnnumbered = QToolButton(self)
|
||||
@@ -652,7 +653,7 @@ class _HeadingsTab(NScrollablePage):
|
||||
|
||||
# Scene Heading
|
||||
sceneHideTip = self._build.getLabel("headings.hideScene")
|
||||
self.lblScene = QLabel(self._build.getLabel("headings.fmtScene"))
|
||||
self.lblScene = QLabel(self._build.getLabel("headings.fmtScene"), self)
|
||||
self.fmtScene = QLineEdit("", self)
|
||||
self.fmtScene.setReadOnly(True)
|
||||
self.btnScene = QToolButton(self)
|
||||
@@ -677,9 +678,36 @@ class _HeadingsTab(NScrollablePage):
|
||||
self.formatBox.addLayout(wrapScene, 3, 1)
|
||||
self.formatBox.addLayout(wrapSceneHide, 3, 2)
|
||||
|
||||
# Alt Scene Heading
|
||||
hardSceneHideTip = self._build.getLabel("headings.hideHardScene")
|
||||
self.lblHScene = QLabel(self._build.getLabel("headings.fmtHardScene"), self)
|
||||
self.fmtHScene = QLineEdit("", self)
|
||||
self.fmtHScene.setReadOnly(True)
|
||||
self.btnHScene = QToolButton(self)
|
||||
self.btnHScene.setIcon(SHARED.theme.getIcon("edit"))
|
||||
self.btnHScene.clicked.connect(lambda: self._editHeading(self.EDIT_HSCENE))
|
||||
self.hdeHScene = QLabel(self.tr("Hide"))
|
||||
self.hdeHScene.setToolTip(hardSceneHideTip)
|
||||
self.swtHScene = NSwitch(self, height=iPx)
|
||||
self.swtHScene.setToolTip(hardSceneHideTip)
|
||||
|
||||
wrapHScene = QHBoxLayout()
|
||||
wrapHScene.addWidget(self.fmtHScene)
|
||||
wrapHScene.addWidget(self.btnHScene)
|
||||
wrapHScene.setSpacing(bSp)
|
||||
|
||||
wrapHSceneHide = QHBoxLayout()
|
||||
wrapHSceneHide.addWidget(self.hdeHScene)
|
||||
wrapHSceneHide.addWidget(self.swtHScene)
|
||||
wrapHSceneHide.setSpacing(bSp)
|
||||
|
||||
self.formatBox.addWidget(self.lblHScene, 4, 0)
|
||||
self.formatBox.addLayout(wrapHScene, 4, 1)
|
||||
self.formatBox.addLayout(wrapHSceneHide, 4, 2)
|
||||
|
||||
# Section Heading
|
||||
sectionHideTip = self._build.getLabel("headings.hideSection")
|
||||
self.lblSection = QLabel(self._build.getLabel("headings.fmtSection"))
|
||||
self.lblSection = QLabel(self._build.getLabel("headings.fmtSection"), self)
|
||||
self.fmtSection = QLineEdit("", self)
|
||||
self.fmtSection.setReadOnly(True)
|
||||
self.btnSection = QToolButton(self)
|
||||
@@ -700,9 +728,9 @@ class _HeadingsTab(NScrollablePage):
|
||||
wrapSectionHide.addWidget(self.swtSection)
|
||||
wrapSectionHide.setSpacing(bSp)
|
||||
|
||||
self.formatBox.addWidget(self.lblSection, 4, 0)
|
||||
self.formatBox.addLayout(wrapSection, 4, 1)
|
||||
self.formatBox.addLayout(wrapSectionHide, 4, 2)
|
||||
self.formatBox.addWidget(self.lblSection, 5, 0)
|
||||
self.formatBox.addLayout(wrapSection, 5, 1)
|
||||
self.formatBox.addLayout(wrapSectionHide, 5, 2)
|
||||
|
||||
# Edit Form
|
||||
# =========
|
||||
@@ -830,8 +858,10 @@ class _HeadingsTab(NScrollablePage):
|
||||
self.fmtChapter.setText(self._build.getStr("headings.fmtChapter"))
|
||||
self.fmtUnnumbered.setText(self._build.getStr("headings.fmtUnnumbered"))
|
||||
self.fmtScene.setText(self._build.getStr("headings.fmtScene"))
|
||||
self.fmtHScene.setText(self._build.getStr("headings.fmtHardScene"))
|
||||
self.fmtSection.setText(self._build.getStr("headings.fmtSection"))
|
||||
self.swtScene.setChecked(self._build.getBool("headings.hideScene"))
|
||||
self.swtHScene.setChecked(self._build.getBool("headings.hideHardScene"))
|
||||
self.swtSection.setChecked(self._build.getBool("headings.hideSection"))
|
||||
self.centerTitle.setChecked(self._build.getBool("headings.centerTitle"))
|
||||
self.centerChapter.setChecked(self._build.getBool("headings.centerChapter"))
|
||||
@@ -844,6 +874,7 @@ class _HeadingsTab(NScrollablePage):
|
||||
def saveContent(self) -> None:
|
||||
"""Save choices back into build object."""
|
||||
self._build.setValue("headings.hideScene", self.swtScene.isChecked())
|
||||
self._build.setValue("headings.hideHardScene", self.swtHScene.isChecked())
|
||||
self._build.setValue("headings.hideSection", self.swtSection.isChecked())
|
||||
self._build.setValue("headings.centerTitle", self.centerTitle.isChecked())
|
||||
self._build.setValue("headings.centerChapter", self.centerChapter.isChecked())
|
||||
@@ -881,6 +912,9 @@ class _HeadingsTab(NScrollablePage):
|
||||
elif heading == self.EDIT_SCENE:
|
||||
text = self.fmtScene.text()
|
||||
label = self._build.getLabel("headings.fmtScene")
|
||||
elif heading == self.EDIT_HSCENE:
|
||||
text = self.fmtHScene.text()
|
||||
label = self._build.getLabel("headings.fmtHardScene")
|
||||
elif heading == self.EDIT_SECTION:
|
||||
text = self.fmtSection.text()
|
||||
label = self._build.getLabel("headings.fmtSection")
|
||||
@@ -916,6 +950,9 @@ class _HeadingsTab(NScrollablePage):
|
||||
elif heading == self.EDIT_SCENE:
|
||||
self.fmtScene.setText(text)
|
||||
self._build.setValue("headings.fmtScene", text)
|
||||
elif heading == self.EDIT_HSCENE:
|
||||
self.fmtHScene.setText(text)
|
||||
self._build.setValue("headings.fmtHardScene", text)
|
||||
elif heading == self.EDIT_SECTION:
|
||||
self.fmtSection.setText(text)
|
||||
self._build.setValue("headings.fmtSection", text)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
%%~name: Another Scene
|
||||
%%~path: 6a2d6d5f4f401/bc0cbd2a407f3
|
||||
%%~kind: NOVEL/DOCUMENT
|
||||
%%~hash: b3f9e4b097f7041c77489876577014c435a8be0c
|
||||
%%~date: Unknown/2023-08-25 16:51:57
|
||||
%%~hash: d35e2629876e627b1a2418affa40d477022984f8
|
||||
%%~date: Unknown/2024-03-11 22:56:28
|
||||
### Another Scene
|
||||
|
||||
@pov: John
|
||||
@@ -13,7 +13,7 @@ Adding more scenes to a chapter is as easy as adding more scene files with a lev
|
||||
|
||||
In fact, if you wish, you can add all the scenes in the chapter file too. All novelWriter cares about is the level of the headings and the order in which they appear.
|
||||
|
||||
### More Scenes
|
||||
###! More Scenes
|
||||
|
||||
@pov: Jane
|
||||
@focus: John
|
||||
|
||||
@@ -196,8 +196,8 @@ def testCoreBuildSettings_BuildValues():
|
||||
assert build.getFloat(floatSetting) == 2.5
|
||||
|
||||
# Check labels
|
||||
assert build.getLabel(strSetting) == "Title Headings"
|
||||
assert BuildSettings.getLabel(strSetting) == "Title Headings"
|
||||
assert build.getLabel(strSetting) == "Partition Format"
|
||||
assert BuildSettings.getLabel(strSetting) == "Partition Format"
|
||||
|
||||
# Pack the values
|
||||
data = build.pack()
|
||||
|
||||
@@ -502,6 +502,19 @@ def testCoreIndex_ScanText(mockGUI, fncPath, mockRnd):
|
||||
assert index._itemIndex[tHandle]["T0001"].paraCount == 1 # type: ignore
|
||||
assert index._itemIndex[tHandle]["T0001"].synopsis == "" # type: ignore
|
||||
|
||||
assert index.scanText(tHandle, (
|
||||
"###! Hard Scene\n\n"
|
||||
"We're no longer following Jane, but John!\n\n"
|
||||
))
|
||||
assert index._itemIndex[cHandle]["T0001"].references == {} # type: ignore
|
||||
assert index._itemIndex[tHandle]["T0001"].level == "H3" # type: ignore
|
||||
assert index._itemIndex[tHandle]["T0001"].line == 1 # type: ignore
|
||||
assert index._itemIndex[tHandle]["T0001"].title == "Hard Scene" # type: ignore
|
||||
assert index._itemIndex[tHandle]["T0001"].charCount == 51 # type: ignore
|
||||
assert index._itemIndex[tHandle]["T0001"].wordCount == 9 # type: ignore
|
||||
assert index._itemIndex[tHandle]["T0001"].paraCount == 1 # type: ignore
|
||||
assert index._itemIndex[tHandle]["T0001"].synopsis == "" # type: ignore
|
||||
|
||||
# Page wo/Title
|
||||
# =============
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ def testCoreToken_Setters(mockGUI):
|
||||
assert tokens._fmtChapter == nwHeadFmt.TITLE
|
||||
assert tokens._fmtUnNum == nwHeadFmt.TITLE
|
||||
assert tokens._fmtScene == nwHeadFmt.TITLE
|
||||
assert tokens._fmtHScene == nwHeadFmt.TITLE
|
||||
assert tokens._fmtSection == nwHeadFmt.TITLE
|
||||
assert tokens._textFont == "Serif"
|
||||
assert tokens._textSize == 11
|
||||
@@ -74,6 +75,7 @@ def testCoreToken_Setters(mockGUI):
|
||||
tokens.setChapterFormat(f"C: {nwHeadFmt.TITLE}")
|
||||
tokens.setUnNumberedFormat(f"U: {nwHeadFmt.TITLE}")
|
||||
tokens.setSceneFormat(f"S: {nwHeadFmt.TITLE}", True)
|
||||
tokens.setHardSceneFormat(f"H: {nwHeadFmt.TITLE}", True)
|
||||
tokens.setSectionFormat(f"X: {nwHeadFmt.TITLE}", True)
|
||||
tokens.setFont("Monospace", 10, True)
|
||||
tokens.setLineHeight(2.0)
|
||||
@@ -97,6 +99,7 @@ def testCoreToken_Setters(mockGUI):
|
||||
assert tokens._fmtChapter == f"C: {nwHeadFmt.TITLE}"
|
||||
assert tokens._fmtUnNum == f"U: {nwHeadFmt.TITLE}"
|
||||
assert tokens._fmtScene == f"S: {nwHeadFmt.TITLE}"
|
||||
assert tokens._fmtHScene == f"H: {nwHeadFmt.TITLE}"
|
||||
assert tokens._fmtSection == f"X: {nwHeadFmt.TITLE}"
|
||||
assert tokens._textFont == "Monospace"
|
||||
assert tokens._textSize == 10
|
||||
@@ -1741,7 +1744,7 @@ def testCoreToken_HeaderCounterAndVisibility(mockGUI):
|
||||
"# Title Two\n\n"
|
||||
"### Scene Three\n\n"
|
||||
"Text\n\n"
|
||||
"### Scene Four\n\n"
|
||||
"###! Scene Four\n\n"
|
||||
"Text\n\n"
|
||||
)
|
||||
md.setTitleFormat(f"T: {nwHeadFmt.TITLE}")
|
||||
@@ -1749,13 +1752,14 @@ def testCoreToken_HeaderCounterAndVisibility(mockGUI):
|
||||
md.setSectionFormat("", True)
|
||||
|
||||
# Static Separator
|
||||
md.setSceneFormat("* * *", False)
|
||||
md.setSceneFormat("~", False)
|
||||
md.setHardSceneFormat("* * *", False)
|
||||
md.tokenizeText()
|
||||
md.doConvert()
|
||||
assert md.result == (
|
||||
"# T: Title One\n\n"
|
||||
"Text\n\n"
|
||||
"* * *\n\n"
|
||||
"~\n\n"
|
||||
"Text\n\n"
|
||||
"# T: Title Two\n\n"
|
||||
"Text\n\n"
|
||||
@@ -1765,6 +1769,7 @@ def testCoreToken_HeaderCounterAndVisibility(mockGUI):
|
||||
|
||||
# Scene Title Formatted
|
||||
md.setSceneFormat(f"S: {nwHeadFmt.TITLE}", False)
|
||||
md.setHardSceneFormat(f"H: {nwHeadFmt.TITLE}", False)
|
||||
md.tokenizeText()
|
||||
md.doConvert()
|
||||
assert md.result == (
|
||||
@@ -1776,7 +1781,7 @@ def testCoreToken_HeaderCounterAndVisibility(mockGUI):
|
||||
"# T: Title Two\n\n"
|
||||
"### S: Scene Three\n\n"
|
||||
"Text\n\n"
|
||||
"### S: Scene Four\n\n"
|
||||
"### H: Scene Four\n\n"
|
||||
"Text\n\n"
|
||||
)
|
||||
|
||||
@@ -1793,7 +1798,7 @@ def testCoreToken_HeaderCounterAndVisibility(mockGUI):
|
||||
"## Chapter Two\n\n"
|
||||
"### Scene Three\n\n"
|
||||
"Text\n\n"
|
||||
"### Scene Four\n\n"
|
||||
"###! Scene Four\n\n"
|
||||
"Text\n\n"
|
||||
)
|
||||
md.setTitleFormat(f"T: {nwHeadFmt.TITLE}")
|
||||
@@ -1802,6 +1807,7 @@ def testCoreToken_HeaderCounterAndVisibility(mockGUI):
|
||||
|
||||
# Static Separator
|
||||
md.setSceneFormat("* * *", False)
|
||||
md.setHardSceneFormat("* * *", False)
|
||||
md.tokenizeText()
|
||||
md.doConvert()
|
||||
assert md.result == (
|
||||
@@ -1818,6 +1824,7 @@ def testCoreToken_HeaderCounterAndVisibility(mockGUI):
|
||||
|
||||
# Scene Title Formatted
|
||||
md.setSceneFormat(f"S: {nwHeadFmt.TITLE}", False)
|
||||
md.setHardSceneFormat(f"H: {nwHeadFmt.TITLE}", False)
|
||||
md.tokenizeText()
|
||||
md.doConvert()
|
||||
assert md.result == (
|
||||
@@ -1830,15 +1837,18 @@ def testCoreToken_HeaderCounterAndVisibility(mockGUI):
|
||||
"## C: Chapter Two\n\n"
|
||||
"### S: Scene Three\n\n"
|
||||
"Text\n\n"
|
||||
"### S: Scene Four\n\n"
|
||||
"### H: Scene Four\n\n"
|
||||
"Text\n\n"
|
||||
)
|
||||
|
||||
# Counter Handling, Novel Titles
|
||||
# ==============================
|
||||
# This also checks that only numbered chapters bump the counter
|
||||
|
||||
md._text = (
|
||||
"#! Novel One\n\n"
|
||||
"##! Prologue\n\n"
|
||||
"Text\n\n"
|
||||
"## Chapter One\n\n"
|
||||
"### Scene One\n\n"
|
||||
"Text\n\n"
|
||||
@@ -1847,9 +1857,11 @@ def testCoreToken_HeaderCounterAndVisibility(mockGUI):
|
||||
"## Chapter Two\n\n"
|
||||
"### Scene Three\n\n"
|
||||
"Text\n\n"
|
||||
"### Scene Four\n\n"
|
||||
"###! Scene Four\n\n"
|
||||
"Text\n\n"
|
||||
"#! Novel Two\n\n"
|
||||
"##! Prologue\n\n"
|
||||
"Text\n\n"
|
||||
"## Chapter One\n\n"
|
||||
"### Scene One\n\n"
|
||||
"Text\n\n"
|
||||
@@ -1858,13 +1870,17 @@ def testCoreToken_HeaderCounterAndVisibility(mockGUI):
|
||||
"## Chapter Two\n\n"
|
||||
"### Scene Three\n\n"
|
||||
"Text\n\n"
|
||||
"### Scene Four\n\n"
|
||||
"###! Scene Four\n\n"
|
||||
"Text\n\n"
|
||||
)
|
||||
md.setTitleFormat(f"T: {nwHeadFmt.TITLE}")
|
||||
md.setChapterFormat(f"C {nwHeadFmt.CH_NUM}: {nwHeadFmt.TITLE}")
|
||||
md.setSceneFormat(f"S {nwHeadFmt.CH_NUM}.{nwHeadFmt.SC_NUM} ({nwHeadFmt.SC_ABS}): "
|
||||
f"{nwHeadFmt.TITLE}", False)
|
||||
md.setSceneFormat(
|
||||
f"S {nwHeadFmt.CH_NUM}.{nwHeadFmt.SC_NUM} ({nwHeadFmt.SC_ABS}): {nwHeadFmt.TITLE}", False
|
||||
)
|
||||
md.setHardSceneFormat(
|
||||
f"H {nwHeadFmt.CH_NUM}.{nwHeadFmt.SC_NUM} ({nwHeadFmt.SC_ABS}): {nwHeadFmt.TITLE}", False
|
||||
)
|
||||
md.setSectionFormat("", True)
|
||||
|
||||
# Two Novel Format
|
||||
@@ -1872,6 +1888,8 @@ def testCoreToken_HeaderCounterAndVisibility(mockGUI):
|
||||
md.doConvert()
|
||||
assert md.result == (
|
||||
"# Novel One\n\n"
|
||||
"## Prologue\n\n"
|
||||
"Text\n\n"
|
||||
"## C 1: Chapter One\n\n"
|
||||
"### S 1.1 (1): Scene One\n\n"
|
||||
"Text\n\n"
|
||||
@@ -1880,9 +1898,11 @@ def testCoreToken_HeaderCounterAndVisibility(mockGUI):
|
||||
"## C 2: Chapter Two\n\n"
|
||||
"### S 2.1 (3): Scene Three\n\n"
|
||||
"Text\n\n"
|
||||
"### S 2.2 (4): Scene Four\n\n"
|
||||
"### H 2.2 (4): Scene Four\n\n"
|
||||
"Text\n\n"
|
||||
"# Novel Two\n\n"
|
||||
"## Prologue\n\n"
|
||||
"Text\n\n"
|
||||
"## C 1: Chapter One\n\n"
|
||||
"### S 1.1 (1): Scene One\n\n"
|
||||
"Text\n\n"
|
||||
@@ -1891,7 +1911,7 @@ def testCoreToken_HeaderCounterAndVisibility(mockGUI):
|
||||
"## C 2: Chapter Two\n\n"
|
||||
"### S 2.1 (3): Scene Three\n\n"
|
||||
"Text\n\n"
|
||||
"### S 2.2 (4): Scene Four\n\n"
|
||||
"### H 2.2 (4): Scene Four\n\n"
|
||||
"Text\n\n"
|
||||
)
|
||||
|
||||
|
||||
@@ -1134,13 +1134,20 @@ def testGuiEditor_BlockFormatting(qtbot, monkeypatch, nwGUI, projPath, ipsumText
|
||||
assert nwGUI.docEditor.getText() == "Title\n\n"
|
||||
assert nwGUI.docEditor.getCursorPosition() == 2
|
||||
|
||||
# Strip Unnumbered CHapter
|
||||
# Strip Unnumbered Chapter
|
||||
nwGUI.docEditor.replaceText("##! Title\n\n")
|
||||
nwGUI.docEditor.setCursorPosition(5)
|
||||
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True
|
||||
assert nwGUI.docEditor.getText() == "Title\n\n"
|
||||
assert nwGUI.docEditor.getCursorPosition() == 1
|
||||
|
||||
# Strip Hard Scene
|
||||
nwGUI.docEditor.replaceText("###! Title\n\n")
|
||||
nwGUI.docEditor.setCursorPosition(6)
|
||||
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True
|
||||
assert nwGUI.docEditor.getText() == "Title\n\n"
|
||||
assert nwGUI.docEditor.getCursorPosition() == 1
|
||||
|
||||
# Strip Text
|
||||
nwGUI.docEditor.replaceText("Generic text\n\n")
|
||||
nwGUI.docEditor.setCursorPosition(5)
|
||||
@@ -1302,6 +1309,13 @@ def testGuiEditor_BlockFormatting(qtbot, monkeypatch, nwGUI, projPath, ipsumText
|
||||
assert nwGUI.docEditor.getText() == "##! Some text\n\n"
|
||||
assert nwGUI.docEditor.getCursorPosition() == 9
|
||||
|
||||
# Hard Scene
|
||||
nwGUI.docEditor.replaceText("Some text\n\n")
|
||||
nwGUI.docEditor.setCursorPosition(5)
|
||||
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_HSC) is True
|
||||
assert nwGUI.docEditor.getText() == "###! Some text\n\n"
|
||||
assert nwGUI.docEditor.getCursorPosition() == 10
|
||||
|
||||
# Left Indent
|
||||
nwGUI.docEditor.replaceText("Some text\n\n")
|
||||
nwGUI.docEditor.setCursorPosition(5)
|
||||
|
||||
@@ -126,6 +126,11 @@ def testGuiMenu_EditFormat(qtbot, monkeypatch, nwGUI, prjLipsum):
|
||||
fmtStr = "##! Pellentesque nec erat ut nulla posuere commodo."
|
||||
assert nwGUI.docEditor.getText()[54:105] == fmtStr
|
||||
|
||||
# Hard Scene
|
||||
nwGUI.mainMenu.aFmtHardSc.activate(QAction.Trigger)
|
||||
fmtStr = "###! Pellentesque nec erat ut nulla posuere commodo."
|
||||
assert nwGUI.docEditor.getText()[54:106] == fmtStr
|
||||
|
||||
# Clear Format
|
||||
nwGUI.mainMenu.aFmtNoFormat.activate(QAction.Trigger)
|
||||
assert nwGUI.docEditor.getText()[54:101] == cleanText
|
||||
|
||||
@@ -327,12 +327,14 @@ def testBuildSettings_Headings(qtbot: QtBot, nwGUI: GuiMain):
|
||||
chTitle = f"Chapter: {nwHeadFmt.TITLE}"
|
||||
unTitle = f"Interlude: {nwHeadFmt.TITLE}"
|
||||
scTitle = f"Scene: {nwHeadFmt.TITLE}"
|
||||
shTitle = f"Hard Scene: {nwHeadFmt.TITLE}"
|
||||
sxTitle = f"Section: {nwHeadFmt.TITLE}"
|
||||
|
||||
build.setValue("headings.fmtTitle", ttTitle)
|
||||
build.setValue("headings.fmtChapter", chTitle)
|
||||
build.setValue("headings.fmtUnnumbered", unTitle)
|
||||
build.setValue("headings.fmtScene", scTitle)
|
||||
build.setValue("headings.fmtHardScene", shTitle)
|
||||
build.setValue("headings.fmtSection", sxTitle)
|
||||
build.setValue("headings.hideScene", False)
|
||||
build.setValue("headings.hideSection", False)
|
||||
@@ -351,6 +353,7 @@ def testBuildSettings_Headings(qtbot: QtBot, nwGUI: GuiMain):
|
||||
assert headTab.fmtChapter.text() == chTitle
|
||||
assert headTab.fmtUnnumbered.text() == unTitle
|
||||
assert headTab.fmtScene.text() == scTitle
|
||||
assert headTab.fmtHScene.text() == shTitle
|
||||
assert headTab.fmtSection.text() == sxTitle
|
||||
assert headTab.swtScene.isChecked() is False
|
||||
assert headTab.swtSection.isChecked() is False
|
||||
@@ -396,6 +399,14 @@ def testBuildSettings_Headings(qtbot: QtBot, nwGUI: GuiMain):
|
||||
headTab.btnApply.click()
|
||||
assert headTab.editTextBox.isEnabled() is False
|
||||
|
||||
# Hard Scene
|
||||
headTab.btnHScene.click()
|
||||
assert headTab._editing == headTab.EDIT_HSCENE
|
||||
assert headTab.editTextBox.isEnabled() is True
|
||||
assert headTab.editTextBox.toPlainText() == shTitle
|
||||
headTab.btnApply.click()
|
||||
assert headTab.editTextBox.isEnabled() is False
|
||||
|
||||
# Section
|
||||
headTab.btnSection.click()
|
||||
assert headTab._editing == headTab.EDIT_SECTION
|
||||
@@ -455,6 +466,11 @@ def testBuildSettings_Headings(qtbot: QtBot, nwGUI: GuiMain):
|
||||
headTab.btnApply.click()
|
||||
assert build.getStr("headings.fmtScene") == nwHeadFmt.TITLE
|
||||
|
||||
headTab.btnHScene.click()
|
||||
headTab.editTextBox.setPlainText(nwHeadFmt.TITLE)
|
||||
headTab.btnApply.click()
|
||||
assert build.getStr("headings.fmtHardScene") == nwHeadFmt.TITLE
|
||||
|
||||
headTab.btnSection.click()
|
||||
headTab.editTextBox.setPlainText(nwHeadFmt.TITLE)
|
||||
headTab.btnApply.click()
|
||||
|
||||
Reference in New Issue
Block a user