Improve GUI text (#1727)
This commit is contained in:
@@ -307,7 +307,7 @@ class NWIndex:
|
|||||||
nTitle = 0 # Line Number of the previous title
|
nTitle = 0 # Line Number of the previous title
|
||||||
cTitle = TT_NONE # Tag of the current title
|
cTitle = TT_NONE # Tag of the current title
|
||||||
pTitle = TT_NONE # Tag of the previous title
|
pTitle = TT_NONE # Tag of the previous title
|
||||||
canSetHeader = True # First header has not yet been set
|
canSetHead = True # First heading has not yet been set
|
||||||
|
|
||||||
lines = text.splitlines()
|
lines = text.splitlines()
|
||||||
for n, line in enumerate(lines, start=1):
|
for n, line in enumerate(lines, start=1):
|
||||||
@@ -320,9 +320,9 @@ class NWIndex:
|
|||||||
if hDepth == "H0":
|
if hDepth == "H0":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if canSetHeader:
|
if canSetHead:
|
||||||
nwItem.setMainHeading(hDepth)
|
nwItem.setMainHeading(hDepth)
|
||||||
canSetHeader = False
|
canSetHead = False
|
||||||
|
|
||||||
cTitle = self._itemIndex.addItemHeading(tHandle, n, hDepth, hText)
|
cTitle = self._itemIndex.addItemHeading(tHandle, n, hDepth, hText)
|
||||||
if cTitle != TT_NONE:
|
if cTitle != TT_NONE:
|
||||||
@@ -383,7 +383,7 @@ class NWIndex:
|
|||||||
return
|
return
|
||||||
|
|
||||||
def _splitHeading(self, line: str) -> tuple[str, str]:
|
def _splitHeading(self, line: str) -> tuple[str, str]:
|
||||||
"""Split a heading into its header level and text value."""
|
"""Split a heading into its heading level and text value."""
|
||||||
if line.startswith("# "):
|
if line.startswith("# "):
|
||||||
return "H1", line[2:].strip()
|
return "H1", line[2:].strip()
|
||||||
elif line.startswith("## "):
|
elif line.startswith("## "):
|
||||||
@@ -515,8 +515,8 @@ class NWIndex:
|
|||||||
"""Get the index data for a given item."""
|
"""Get the index data for a given item."""
|
||||||
return self._itemIndex[tHandle]
|
return self._itemIndex[tHandle]
|
||||||
|
|
||||||
def getItemHeader(self, tHandle: str, sTitle: str) -> IndexHeading | None:
|
def getItemHeading(self, tHandle: str, sTitle: str) -> IndexHeading | None:
|
||||||
"""Get the header entry for a specific item and heading."""
|
"""Get the heading entry for a specific item and heading."""
|
||||||
tItem = self._itemIndex[tHandle]
|
tItem = self._itemIndex[tHandle]
|
||||||
if isinstance(tItem, IndexItem):
|
if isinstance(tItem, IndexItem):
|
||||||
return tItem[sTitle]
|
return tItem[sTitle]
|
||||||
@@ -825,7 +825,7 @@ class ItemIndex:
|
|||||||
class around a single storage dictionary with a set of utility
|
class around a single storage dictionary with a set of utility
|
||||||
functions for setting and accessing the index data. Each indexed
|
functions for setting and accessing the index data. Each indexed
|
||||||
item is stored in an IndexItem object, which again holds an
|
item is stored in an IndexItem object, which again holds an
|
||||||
IndexHeading object for each header of the text.
|
IndexHeading object for each heading of the text.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ("_project", "_items")
|
__slots__ = ("_project", "_items")
|
||||||
@@ -1200,7 +1200,7 @@ class IndexHeading:
|
|||||||
##
|
##
|
||||||
|
|
||||||
def setLevel(self, level: str) -> None:
|
def setLevel(self, level: str) -> None:
|
||||||
"""Set the level of the header if it's a valid value."""
|
"""Set the level of the heading if it's a valid value."""
|
||||||
if level in nwHeaders.H_VALID:
|
if level in nwHeaders.H_VALID:
|
||||||
self._level = level
|
self._level = level
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -89,10 +89,10 @@ class Tokenizer(ABC):
|
|||||||
T_KEYWORD = 5 # Command line
|
T_KEYWORD = 5 # Command line
|
||||||
T_TITLE = 6 # Title
|
T_TITLE = 6 # Title
|
||||||
T_UNNUM = 7 # Unnumbered
|
T_UNNUM = 7 # Unnumbered
|
||||||
T_HEAD1 = 8 # Header 1
|
T_HEAD1 = 8 # Heading 1
|
||||||
T_HEAD2 = 9 # Header 2
|
T_HEAD2 = 9 # Heading 2
|
||||||
T_HEAD3 = 10 # Header 3
|
T_HEAD3 = 10 # Heading 3
|
||||||
T_HEAD4 = 11 # Header 4
|
T_HEAD4 = 11 # Heading 4
|
||||||
T_TEXT = 12 # Text line
|
T_TEXT = 12 # Text line
|
||||||
T_SEP = 13 # Scene separator
|
T_SEP = 13 # Scene separator
|
||||||
T_SKIP = 14 # Paragraph break
|
T_SKIP = 14 # Paragraph break
|
||||||
@@ -158,10 +158,10 @@ class Tokenizer(ABC):
|
|||||||
self._fmtScene = nwHeadFmt.TITLE # Formatting for scenes
|
self._fmtScene = nwHeadFmt.TITLE # Formatting for scenes
|
||||||
self._fmtSection = nwHeadFmt.TITLE # Formatting for sections
|
self._fmtSection = nwHeadFmt.TITLE # Formatting for sections
|
||||||
|
|
||||||
self._hideScene = False # Do not include scene headers
|
self._hideScene = False # Do not include scene headings
|
||||||
self._hideSection = False # Do not include section headers
|
self._hideSection = False # Do not include section headings
|
||||||
|
|
||||||
self._linkHeaders = False # Add an anchor before headers
|
self._linkHeaders = False # Add an anchor before headings
|
||||||
|
|
||||||
self._titleStyle = self.A_CENTRE | self.A_PBB
|
self._titleStyle = self.A_CENTRE | self.A_PBB
|
||||||
self._chapterStyle = self.A_PBB
|
self._chapterStyle = self.A_PBB
|
||||||
@@ -309,22 +309,22 @@ class Tokenizer(ABC):
|
|||||||
return
|
return
|
||||||
|
|
||||||
def setHead1Margins(self, upper: float, lower: float) -> None:
|
def setHead1Margins(self, upper: float, lower: float) -> None:
|
||||||
"""Set the upper and lower header 1 margin."""
|
"""Set the upper and lower heading 1 margin."""
|
||||||
self._marginHead1 = (float(upper), float(lower))
|
self._marginHead1 = (float(upper), float(lower))
|
||||||
return
|
return
|
||||||
|
|
||||||
def setHead2Margins(self, upper: float, lower: float) -> None:
|
def setHead2Margins(self, upper: float, lower: float) -> None:
|
||||||
"""Set the upper and lower header 2 margin."""
|
"""Set the upper and lower heading 2 margin."""
|
||||||
self._marginHead2 = (float(upper), float(lower))
|
self._marginHead2 = (float(upper), float(lower))
|
||||||
return
|
return
|
||||||
|
|
||||||
def setHead3Margins(self, upper: float, lower: float) -> None:
|
def setHead3Margins(self, upper: float, lower: float) -> None:
|
||||||
"""Set the upper and lower header 3 margin."""
|
"""Set the upper and lower heading 3 margin."""
|
||||||
self._marginHead3 = (float(upper), float(lower))
|
self._marginHead3 = (float(upper), float(lower))
|
||||||
return
|
return
|
||||||
|
|
||||||
def setHead4Margins(self, upper: float, lower: float) -> None:
|
def setHead4Margins(self, upper: float, lower: float) -> None:
|
||||||
"""Set the upper and lower header 4 margin."""
|
"""Set the upper and lower heading 4 margin."""
|
||||||
self._marginHead4 = (float(upper), float(lower))
|
self._marginHead4 = (float(upper), float(lower))
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -338,8 +338,8 @@ class Tokenizer(ABC):
|
|||||||
self._marginMeta = (float(upper), float(lower))
|
self._marginMeta = (float(upper), float(lower))
|
||||||
return
|
return
|
||||||
|
|
||||||
def setLinkHeaders(self, state: bool) -> None:
|
def setLinkHeadings(self, state: bool) -> None:
|
||||||
"""Enable or disable adding an anchor before headers."""
|
"""Enable or disable adding an anchor before headings."""
|
||||||
self._linkHeaders = state
|
self._linkHeaders = state
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -442,7 +442,7 @@ class Tokenizer(ABC):
|
|||||||
|
|
||||||
def tokenizeText(self) -> None:
|
def tokenizeText(self) -> None:
|
||||||
"""Scan the text for either lines starting with specific
|
"""Scan the text for either lines starting with specific
|
||||||
characters that indicate headers, comments, commands etc, or
|
characters that indicate headings, comments, commands etc, or
|
||||||
just contain plain text. In the case of plain text, apply the
|
just contain plain text. In the case of plain text, apply the
|
||||||
same RegExes that the syntax highlighter uses and save the
|
same RegExes that the syntax highlighter uses and save the
|
||||||
locations of these formatting tags into the token array.
|
locations of these formatting tags into the token array.
|
||||||
@@ -450,7 +450,7 @@ class Tokenizer(ABC):
|
|||||||
The format of the token list is an entry with a five-tuple for
|
The format of the token list is an entry with a five-tuple for
|
||||||
each line in the file. The tuple is as follows:
|
each line in the file. The tuple is as follows:
|
||||||
1: The type of the block, self.T_*
|
1: The type of the block, self.T_*
|
||||||
2: The header number under which the text is placed
|
2: The heading number under which the text is placed
|
||||||
3: The text content of the block, without leading tags
|
3: The text content of the block, without leading tags
|
||||||
4: The internal formatting map of the text, self.FMT_*
|
4: The internal formatting map of the text, self.FMT_*
|
||||||
5: The style of the block, self.A_*
|
5: The style of the block, self.A_*
|
||||||
@@ -557,9 +557,9 @@ class Tokenizer(ABC):
|
|||||||
tmpMarkdown.append(f"{aLine}\n")
|
tmpMarkdown.append(f"{aLine}\n")
|
||||||
|
|
||||||
elif aLine[:2] == "# ":
|
elif aLine[:2] == "# ":
|
||||||
# Partition Headers
|
# Partition Headings
|
||||||
# =================
|
# ==================
|
||||||
# Partition headers are only formatted in novel documents, and
|
# Partition headings are only formatted in novel documents, and
|
||||||
# otherwise unchanged. Scene separators are disabled
|
# otherwise unchanged. Scene separators are disabled
|
||||||
# immediately after partitions, and scene numbers are reset.
|
# immediately after partitions, and scene numbers are reset.
|
||||||
|
|
||||||
@@ -579,12 +579,12 @@ class Tokenizer(ABC):
|
|||||||
tmpMarkdown.append(f"{aLine}\n")
|
tmpMarkdown.append(f"{aLine}\n")
|
||||||
|
|
||||||
elif aLine[:3] == "## ":
|
elif aLine[:3] == "## ":
|
||||||
# Chapter Headers
|
# Chapter Headings
|
||||||
# ===============
|
# ================
|
||||||
# Chapter headers are only formatted in novel documents, and
|
# Chapter headings are only formatted in novel documents, and
|
||||||
# otherwise unchanged. Chapter numbers are bumped before the
|
# otherwise unchanged. Chapter numbers are bumped before the
|
||||||
# heading is formatted. Scene separators are disabled
|
# heading is formatted. Scene separators are disabled
|
||||||
# immediately after chapter headers, and scene numbers are
|
# immediately after chapter headings, and scene numbers are
|
||||||
# reset.
|
# reset.
|
||||||
|
|
||||||
nHead += 1
|
nHead += 1
|
||||||
@@ -604,15 +604,15 @@ class Tokenizer(ABC):
|
|||||||
tmpMarkdown.append(f"{aLine}\n")
|
tmpMarkdown.append(f"{aLine}\n")
|
||||||
|
|
||||||
elif aLine[:4] == "### ":
|
elif aLine[:4] == "### ":
|
||||||
# Scene Headers
|
# Scene Headings
|
||||||
# =============
|
# ==============
|
||||||
# Scene headers in novel documents are treated as centred
|
# Scene headings in novel documents are treated as centred
|
||||||
# separators if the formatting does not change the text. If the
|
# separators if the formatting does not change the text. If the
|
||||||
# format is empty, the scene can be hidden or a blank paragraph
|
# format is empty, the scene can be hidden or a blank paragraph
|
||||||
# (skip). When the scene title has static text or no text, it
|
# (skip). When the scene title has static text or no text, it
|
||||||
# is always ignored if the noSep flag is set. This prevents
|
# is always ignored if the noSep flag is set. This prevents
|
||||||
# separators immediately after other titles. Scene numbers are
|
# separators immediately after other titles. Scene numbers are
|
||||||
# always incremented before formatting. For notes, the header
|
# always incremented before formatting. For notes, the heading
|
||||||
# is unchanged.
|
# is unchanged.
|
||||||
|
|
||||||
nHead += 1
|
nHead += 1
|
||||||
@@ -639,12 +639,12 @@ class Tokenizer(ABC):
|
|||||||
tmpMarkdown.append(f"{aLine}\n")
|
tmpMarkdown.append(f"{aLine}\n")
|
||||||
|
|
||||||
elif aLine[:5] == "#### ":
|
elif aLine[:5] == "#### ":
|
||||||
# Section Headers
|
# Section Headings
|
||||||
# ===============
|
# =================
|
||||||
# Section headers in novel docs are treated as centred
|
# Section headings in novel docs are treated as centred
|
||||||
# separators if the formatting does not change the text. If the
|
# separators if the formatting does not change the text. If the
|
||||||
# format is empty, the section can be hidden or a blank
|
# format is empty, the section can be hidden or a blank
|
||||||
# paragraph (skip). For notes, the header is unchanged.
|
# paragraph (skip). For notes, the heading is unchanged.
|
||||||
|
|
||||||
nHead += 1
|
nHead += 1
|
||||||
tText = aLine[5:].strip()
|
tText = aLine[5:].strip()
|
||||||
@@ -682,10 +682,10 @@ class Tokenizer(ABC):
|
|||||||
tmpMarkdown.append(f"{aLine}\n")
|
tmpMarkdown.append(f"{aLine}\n")
|
||||||
|
|
||||||
elif aLine[:4] == "##! ":
|
elif aLine[:4] == "##! ":
|
||||||
# Unnumbered Chapter Header
|
# Unnumbered Chapter Headings
|
||||||
# =========================
|
# ===========================
|
||||||
# Unnumbered chapters are only meaningful in Novel docs, so if
|
# Unnumbered chapters are only meaningful in Novel docs, so if
|
||||||
# we're in a note, we convert them to a plain level 2 header.
|
# we're in a note, we convert them to a plain level 2 heading.
|
||||||
|
|
||||||
nHead += 1
|
nHead += 1
|
||||||
tText = aLine[4:].strip()
|
tText = aLine[4:].strip()
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class GuiDocSplit(QDialog):
|
|||||||
|
|
||||||
self.setWindowTitle(self.tr("Split Document"))
|
self.setWindowTitle(self.tr("Split Document"))
|
||||||
|
|
||||||
self.headLabel = QLabel("<b>{0}</b>".format(self.tr("Document Headers")))
|
self.headLabel = QLabel("<b>{0}</b>".format(self.tr("Document Headings")))
|
||||||
self.helpLabel = NColourLabel(
|
self.helpLabel = NColourLabel(
|
||||||
self.tr("Select the maximum level to split into files."),
|
self.tr("Select the maximum level to split into files."),
|
||||||
SHARED.theme.helpText, parent=self, wrap=True
|
SHARED.theme.helpText, parent=self, wrap=True
|
||||||
@@ -74,17 +74,17 @@ class GuiDocSplit(QDialog):
|
|||||||
intoFolder = pOptions.getBool("GuiDocSplit", "intoFolder", True)
|
intoFolder = pOptions.getBool("GuiDocSplit", "intoFolder", True)
|
||||||
docHierarchy = pOptions.getBool("GuiDocSplit", "docHierarchy", True)
|
docHierarchy = pOptions.getBool("GuiDocSplit", "docHierarchy", True)
|
||||||
|
|
||||||
# Header Selection
|
# Heading Selection
|
||||||
self.listBox = QListWidget()
|
self.listBox = QListWidget()
|
||||||
self.listBox.setDragDropMode(QAbstractItemView.NoDragDrop)
|
self.listBox.setDragDropMode(QAbstractItemView.NoDragDrop)
|
||||||
self.listBox.setMinimumWidth(CONFIG.pxInt(400))
|
self.listBox.setMinimumWidth(CONFIG.pxInt(400))
|
||||||
self.listBox.setMinimumHeight(CONFIG.pxInt(180))
|
self.listBox.setMinimumHeight(CONFIG.pxInt(180))
|
||||||
|
|
||||||
self.splitLevel = QComboBox(self)
|
self.splitLevel = QComboBox(self)
|
||||||
self.splitLevel.addItem(self.tr("Split on Header Level 1 (Title)"), 1)
|
self.splitLevel.addItem(self.tr("Split on Heading Level 1 (Partition)"), 1)
|
||||||
self.splitLevel.addItem(self.tr("Split up to Header Level 2 (Chapter)"), 2)
|
self.splitLevel.addItem(self.tr("Split up to Heading Level 2 (Chapter)"), 2)
|
||||||
self.splitLevel.addItem(self.tr("Split up to Header Level 3 (Scene)"), 3)
|
self.splitLevel.addItem(self.tr("Split up to Heading Level 3 (Scene)"), 3)
|
||||||
self.splitLevel.addItem(self.tr("Split up to Header Level 4 (Section)"), 4)
|
self.splitLevel.addItem(self.tr("Split up to Heading Level 4 (Section)"), 4)
|
||||||
spIndex = self.splitLevel.findData(spLevel)
|
spIndex = self.splitLevel.findData(spLevel)
|
||||||
if spIndex != -1:
|
if spIndex != -1:
|
||||||
self.splitLevel.setCurrentIndex(spIndex)
|
self.splitLevel.setCurrentIndex(spIndex)
|
||||||
|
|||||||
@@ -90,10 +90,10 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
"header2": self._makeFormat(SHARED.theme.colHead, "bold", 1.6),
|
"header2": self._makeFormat(SHARED.theme.colHead, "bold", 1.6),
|
||||||
"header3": self._makeFormat(SHARED.theme.colHead, "bold", 1.4),
|
"header3": self._makeFormat(SHARED.theme.colHead, "bold", 1.4),
|
||||||
"header4": self._makeFormat(SHARED.theme.colHead, "bold", 1.2),
|
"header4": self._makeFormat(SHARED.theme.colHead, "bold", 1.2),
|
||||||
"header1h": self._makeFormat(SHARED.theme.colHeadH, "bold", 1.8),
|
"head1h": self._makeFormat(SHARED.theme.colHeadH, "bold", 1.8),
|
||||||
"header2h": self._makeFormat(SHARED.theme.colHeadH, "bold", 1.6),
|
"head2h": self._makeFormat(SHARED.theme.colHeadH, "bold", 1.6),
|
||||||
"header3h": self._makeFormat(SHARED.theme.colHeadH, "bold", 1.4),
|
"head3h": self._makeFormat(SHARED.theme.colHeadH, "bold", 1.4),
|
||||||
"header4h": self._makeFormat(SHARED.theme.colHeadH, "bold", 1.2),
|
"head4h": self._makeFormat(SHARED.theme.colHeadH, "bold", 1.2),
|
||||||
"bold": self._makeFormat(colEmph, "bold"),
|
"bold": self._makeFormat(colEmph, "bold"),
|
||||||
"italic": self._makeFormat(colEmph, "italic"),
|
"italic": self._makeFormat(colEmph, "italic"),
|
||||||
"strike": self._makeFormat(SHARED.theme.colHidden, "strike"),
|
"strike": self._makeFormat(SHARED.theme.colHidden, "strike"),
|
||||||
@@ -303,28 +303,28 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
elif text.startswith(("# ", "#! ", "## ", "##! ", "### ", "#### ")):
|
elif text.startswith(("# ", "#! ", "## ", "##! ", "### ", "#### ")):
|
||||||
self.setCurrentBlockState(self.BLOCK_TITLE)
|
self.setCurrentBlockState(self.BLOCK_TITLE)
|
||||||
|
|
||||||
if text.startswith("# "): # Header 1
|
if text.startswith("# "): # Heading 1
|
||||||
self.setFormat(0, 1, self._hStyles["header1h"])
|
self.setFormat(0, 1, self._hStyles["head1h"])
|
||||||
self.setFormat(1, len(text), self._hStyles["header1"])
|
self.setFormat(1, len(text), self._hStyles["header1"])
|
||||||
|
|
||||||
elif text.startswith("## "): # Header 2
|
elif text.startswith("## "): # Heading 2
|
||||||
self.setFormat(0, 2, self._hStyles["header2h"])
|
self.setFormat(0, 2, self._hStyles["head2h"])
|
||||||
self.setFormat(2, len(text), self._hStyles["header2"])
|
self.setFormat(2, len(text), self._hStyles["header2"])
|
||||||
|
|
||||||
elif text.startswith("### "): # Header 3
|
elif text.startswith("### "): # Heading 3
|
||||||
self.setFormat(0, 3, self._hStyles["header3h"])
|
self.setFormat(0, 3, self._hStyles["head3h"])
|
||||||
self.setFormat(3, len(text), self._hStyles["header3"])
|
self.setFormat(3, len(text), self._hStyles["header3"])
|
||||||
|
|
||||||
elif text.startswith("#### "): # Header 4
|
elif text.startswith("#### "): # Heading 4
|
||||||
self.setFormat(0, 4, self._hStyles["header4h"])
|
self.setFormat(0, 4, self._hStyles["head4h"])
|
||||||
self.setFormat(4, len(text), self._hStyles["header4"])
|
self.setFormat(4, len(text), self._hStyles["header4"])
|
||||||
|
|
||||||
elif text.startswith("#! "): # Title
|
elif text.startswith("#! "): # Title
|
||||||
self.setFormat(0, 2, self._hStyles["header1h"])
|
self.setFormat(0, 2, self._hStyles["head1h"])
|
||||||
self.setFormat(2, len(text), self._hStyles["header1"])
|
self.setFormat(2, len(text), self._hStyles["header1"])
|
||||||
|
|
||||||
elif text.startswith("##! "): # Unnumbered
|
elif text.startswith("##! "): # Unnumbered
|
||||||
self.setFormat(0, 3, self._hStyles["header2h"])
|
self.setFormat(0, 3, self._hStyles["head2h"])
|
||||||
self.setFormat(3, len(text), self._hStyles["header2"])
|
self.setFormat(3, len(text), self._hStyles["header2"])
|
||||||
|
|
||||||
elif text.startswith("%"): # Comments
|
elif text.startswith("%"): # Comments
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ class GuiDocViewer(QTextBrowser):
|
|||||||
sPos = self.verticalScrollBar().value()
|
sPos = self.verticalScrollBar().value()
|
||||||
aDoc = ToHtml(SHARED.project)
|
aDoc = ToHtml(SHARED.project)
|
||||||
aDoc.setPreview(CONFIG.viewComments, CONFIG.viewSynopsis)
|
aDoc.setPreview(CONFIG.viewComments, CONFIG.viewSynopsis)
|
||||||
aDoc.setLinkHeaders(True)
|
aDoc.setLinkHeadings(True)
|
||||||
|
|
||||||
# Be extra careful here to prevent crashes when first opening a
|
# Be extra careful here to prevent crashes when first opening a
|
||||||
# project as a crash here leaves no way of recovering.
|
# project as a crash here leaves no way of recovering.
|
||||||
|
|||||||
+12
-12
@@ -693,29 +693,29 @@ class GuiMainMenu(QMenuBar):
|
|||||||
# Format > Separator
|
# Format > Separator
|
||||||
self.fmtMenu.addSeparator()
|
self.fmtMenu.addSeparator()
|
||||||
|
|
||||||
# Format > Header 1 (Partition)
|
# Format > Heading 1 (Partition)
|
||||||
self.aFmtHead1 = self.fmtMenu.addAction(self.tr("Header 1 (Partition)"))
|
self.aFmtHead1 = self.fmtMenu.addAction(self.tr("Heading 1 (Partition)"))
|
||||||
self.aFmtHead1.setShortcut("Ctrl+1")
|
self.aFmtHead1.setShortcut("Ctrl+1")
|
||||||
self.aFmtHead1.triggered.connect(
|
self.aFmtHead1.triggered.connect(
|
||||||
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H1)
|
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H1)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Format > Header 2 (Chapter)
|
# Format > Heading 2 (Chapter)
|
||||||
self.aFmtHead2 = self.fmtMenu.addAction(self.tr("Header 2 (Chapter)"))
|
self.aFmtHead2 = self.fmtMenu.addAction(self.tr("Heading 2 (Chapter)"))
|
||||||
self.aFmtHead2.setShortcut("Ctrl+2")
|
self.aFmtHead2.setShortcut("Ctrl+2")
|
||||||
self.aFmtHead2.triggered.connect(
|
self.aFmtHead2.triggered.connect(
|
||||||
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H2)
|
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H2)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Format > Header 3 (Scene)
|
# Format > Heading 3 (Scene)
|
||||||
self.aFmtHead3 = self.fmtMenu.addAction(self.tr("Header 3 (Scene)"))
|
self.aFmtHead3 = self.fmtMenu.addAction(self.tr("Heading 3 (Scene)"))
|
||||||
self.aFmtHead3.setShortcut("Ctrl+3")
|
self.aFmtHead3.setShortcut("Ctrl+3")
|
||||||
self.aFmtHead3.triggered.connect(
|
self.aFmtHead3.triggered.connect(
|
||||||
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H3)
|
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H3)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Format > Header 4 (Section)
|
# Format > Heading 4 (Section)
|
||||||
self.aFmtHead4 = self.fmtMenu.addAction(self.tr("Header 4 (Section)"))
|
self.aFmtHead4 = self.fmtMenu.addAction(self.tr("Heading 4 (Section)"))
|
||||||
self.aFmtHead4.setShortcut("Ctrl+4")
|
self.aFmtHead4.setShortcut("Ctrl+4")
|
||||||
self.aFmtHead4.triggered.connect(
|
self.aFmtHead4.triggered.connect(
|
||||||
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H4)
|
lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H4)
|
||||||
@@ -804,14 +804,14 @@ class GuiMainMenu(QMenuBar):
|
|||||||
# Format > Separator
|
# Format > Separator
|
||||||
self.fmtMenu.addSeparator()
|
self.fmtMenu.addSeparator()
|
||||||
|
|
||||||
# Format > Replace Single Quotes
|
# Format > Replace Straight Single Quotes
|
||||||
self.aFmtReplSng = self.fmtMenu.addAction(self.tr("Convert Single Quotes"))
|
self.aFmtReplSng = self.fmtMenu.addAction(self.tr("Replace Straight Single Quotes"))
|
||||||
self.aFmtReplSng.triggered.connect(
|
self.aFmtReplSng.triggered.connect(
|
||||||
lambda: self.requestDocAction.emit(nwDocAction.REPL_SNG)
|
lambda: self.requestDocAction.emit(nwDocAction.REPL_SNG)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Format > Replace Double Quotes
|
# Format > Replace Straight Double Quotes
|
||||||
self.aFmtReplDbl = self.fmtMenu.addAction(self.tr("Convert Double Quotes"))
|
self.aFmtReplDbl = self.fmtMenu.addAction(self.tr("Replace Straight Double Quotes"))
|
||||||
self.aFmtReplDbl.triggered.connect(
|
self.aFmtReplDbl.triggered.connect(
|
||||||
lambda: self.requestDocAction.emit(nwDocAction.REPL_DBL)
|
lambda: self.requestDocAction.emit(nwDocAction.REPL_DBL)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -750,7 +750,7 @@ class GuiNovelTree(QTreeWidget):
|
|||||||
logger.debug("Generating meta data tooltip for '%s:%s'", tHandle, sTitle)
|
logger.debug("Generating meta data tooltip for '%s:%s'", tHandle, sTitle)
|
||||||
|
|
||||||
pIndex = SHARED.project.index
|
pIndex = SHARED.project.index
|
||||||
novIdx = pIndex.getItemHeader(tHandle, sTitle)
|
novIdx = pIndex.getItemHeading(tHandle, sTitle)
|
||||||
refTags = pIndex.getReferences(tHandle, sTitle)
|
refTags = pIndex.getReferences(tHandle, sTitle)
|
||||||
if not novIdx:
|
if not novIdx:
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1020,7 +1020,7 @@ class GuiOutlineDetails(QScrollArea):
|
|||||||
"""
|
"""
|
||||||
pIndex = SHARED.project.index
|
pIndex = SHARED.project.index
|
||||||
nwItem = SHARED.project.tree[tHandle]
|
nwItem = SHARED.project.tree[tHandle]
|
||||||
novIdx = pIndex.getItemHeader(tHandle, sTitle)
|
novIdx = pIndex.getItemHeading(tHandle, sTitle)
|
||||||
novRefs = pIndex.getReferences(tHandle, sTitle)
|
novRefs = pIndex.getReferences(tHandle, sTitle)
|
||||||
if nwItem and novIdx:
|
if nwItem and novIdx:
|
||||||
self.titleLabel.setText("<b>%s</b>" % self.tr(self.LVL_MAP.get(novIdx.level, "H1")))
|
self.titleLabel.setText("<b>%s</b>" % self.tr(self.LVL_MAP.get(novIdx.level, "H1")))
|
||||||
|
|||||||
@@ -1834,7 +1834,7 @@ class _TreeContextMenu(QMenu):
|
|||||||
|
|
||||||
def _itemHeader(self) -> None:
|
def _itemHeader(self) -> None:
|
||||||
"""Check if there is a header that can be used for rename."""
|
"""Check if there is a header that can be used for rename."""
|
||||||
if hItem := SHARED.project.index.getItemHeader(self._handle, "T0001"):
|
if hItem := SHARED.project.index.getItemHeading(self._handle, "T0001"):
|
||||||
action = self.addAction(self.tr("Rename to Heading"))
|
action = self.addAction(self.tr("Rename to Heading"))
|
||||||
action.triggered.connect(
|
action.triggered.connect(
|
||||||
lambda: self.projTree.renameTreeItem(self._handle, hItem.title)
|
lambda: self.projTree.renameTreeItem(self._handle, hItem.title)
|
||||||
@@ -1933,7 +1933,7 @@ class _TreeContextMenu(QMenu):
|
|||||||
action.triggered.connect(lambda: tree._mergeDocuments(tHandle, True))
|
action.triggered.connect(lambda: tree._mergeDocuments(tHandle, True))
|
||||||
|
|
||||||
if isFile:
|
if isFile:
|
||||||
action = menu.addAction(self.tr("Split Document by Headers"))
|
action = menu.addAction(self.tr("Split Document by Headings"))
|
||||||
action.triggered.connect(lambda: tree._splitDocument(tHandle))
|
action.triggered.connect(lambda: tree._splitDocument(tHandle))
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -1947,11 +1947,9 @@ class _TreeContextMenu(QMenu):
|
|||||||
action.triggered.connect(lambda: tree.setExpandedFromHandle(tHandle, True))
|
action.triggered.connect(lambda: tree.setExpandedFromHandle(tHandle, True))
|
||||||
action = self.addAction(self.tr("Collapse All"))
|
action = self.addAction(self.tr("Collapse All"))
|
||||||
action.triggered.connect(lambda: tree.setExpandedFromHandle(tHandle, False))
|
action.triggered.connect(lambda: tree.setExpandedFromHandle(tHandle, False))
|
||||||
action = self.addAction(self.tr("Duplicate from Here"))
|
|
||||||
action.triggered.connect(lambda: tree._duplicateFromHandle(tHandle))
|
action = self.addAction(self.tr("Duplicate"))
|
||||||
elif isFile:
|
action.triggered.connect(lambda: tree._duplicateFromHandle(tHandle))
|
||||||
action = self.addAction(self.tr("Duplicate Document"))
|
|
||||||
action.triggered.connect(lambda: tree._duplicateFromHandle(tHandle))
|
|
||||||
|
|
||||||
if self._item.itemClass == nwItemClass.TRASH or isRoot or (isFolder and not hasChild):
|
if self._item.itemClass == nwItemClass.TRASH or isRoot or (isFolder and not hasChild):
|
||||||
action = self.addAction(self.tr("Delete Permanently"))
|
action = self.addAction(self.tr("Delete Permanently"))
|
||||||
|
|||||||
@@ -642,7 +642,7 @@ class GuiIcons:
|
|||||||
def getItemIcon(self, tType: nwItemType, tClass: nwItemClass,
|
def getItemIcon(self, tType: nwItemType, tClass: nwItemClass,
|
||||||
tLayout: nwItemLayout, hLevel: str = "H0") -> QIcon:
|
tLayout: nwItemLayout, hLevel: str = "H0") -> QIcon:
|
||||||
"""Get the correct icon for a project item based on type, class
|
"""Get the correct icon for a project item based on type, class
|
||||||
and header level
|
and heading level
|
||||||
"""
|
"""
|
||||||
iconName = None
|
iconName = None
|
||||||
if tType == nwItemType.ROOT:
|
if tType == nwItemType.ROOT:
|
||||||
@@ -668,7 +668,7 @@ class GuiIcons:
|
|||||||
return self.getIcon(iconName)
|
return self.getIcon(iconName)
|
||||||
|
|
||||||
def getHeaderDecoration(self, hLevel: int) -> QPixmap:
|
def getHeaderDecoration(self, hLevel: int) -> QPixmap:
|
||||||
"""Get the decoration for a specific header level."""
|
"""Get the decoration for a specific heading level."""
|
||||||
if not self._headerDec:
|
if not self._headerDec:
|
||||||
iPx = self.mainTheme.baseIconSize
|
iPx = self.mainTheme.baseIconSize
|
||||||
self._headerDec = [
|
self._headerDec = [
|
||||||
@@ -681,7 +681,7 @@ class GuiIcons:
|
|||||||
return self._headerDec[minmax(hLevel, 0, 4)]
|
return self._headerDec[minmax(hLevel, 0, 4)]
|
||||||
|
|
||||||
def getHeaderDecorationNarrow(self, hLevel: int) -> QPixmap:
|
def getHeaderDecorationNarrow(self, hLevel: int) -> QPixmap:
|
||||||
"""Get the narrow decoration for a specific header level."""
|
"""Get the narrow decoration for a specific heading level."""
|
||||||
if not self._headerDecNarrow:
|
if not self._headerDecNarrow:
|
||||||
iPx = self.mainTheme.baseIconSize
|
iPx = self.mainTheme.baseIconSize
|
||||||
self._headerDecNarrow = [
|
self._headerDecNarrow = [
|
||||||
|
|||||||
@@ -736,7 +736,7 @@ class GuiMain(QMainWindow):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
if tHandle is not None and sTitle is not None:
|
if tHandle is not None and sTitle is not None:
|
||||||
hItem = SHARED.project.index.getItemHeader(tHandle, sTitle)
|
hItem = SHARED.project.index.getItemHeading(tHandle, sTitle)
|
||||||
if hItem is not None:
|
if hItem is not None:
|
||||||
tLine = hItem.line
|
tLine = hItem.line
|
||||||
|
|
||||||
@@ -1144,7 +1144,7 @@ class GuiMain(QMainWindow):
|
|||||||
if tHandle is not None:
|
if tHandle is not None:
|
||||||
if mode == nwDocMode.EDIT:
|
if mode == nwDocMode.EDIT:
|
||||||
tLine = None
|
tLine = None
|
||||||
hItem = SHARED.project.index.getItemHeader(tHandle, sTitle)
|
hItem = SHARED.project.index.getItemHeading(tHandle, sTitle)
|
||||||
if hItem is not None:
|
if hItem is not None:
|
||||||
tLine = hItem.line
|
tLine = hItem.line
|
||||||
self.openDocument(tHandle, tLine=tLine, changeFocus=setFocus)
|
self.openDocument(tHandle, tLine=tLine, changeFocus=setFocus)
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ def preProcessText(text: str, keepHeaders: bool = True) -> list[str]:
|
|||||||
|
|
||||||
def standardCounter(text: str) -> tuple[int, int, int]:
|
def standardCounter(text: str) -> tuple[int, int, int]:
|
||||||
"""A counter that counts paragraphs, words and characters.
|
"""A counter that counts paragraphs, words and characters.
|
||||||
This is the standard counter that includes headers in the word and
|
This is the standard counter that includes headings in the word and
|
||||||
character counts.
|
character counts.
|
||||||
"""
|
"""
|
||||||
cCount = 0
|
cCount = 0
|
||||||
|
|||||||
@@ -1011,10 +1011,10 @@ class _StatsWidget(QWidget):
|
|||||||
|
|
||||||
self.leftForm = QFormLayout()
|
self.leftForm = QFormLayout()
|
||||||
self.leftForm.addRow(self.tr("Words"), self.maxTotalWords)
|
self.leftForm.addRow(self.tr("Words"), self.maxTotalWords)
|
||||||
self.leftForm.addRow(self.tr("Header Words"), self.maxHeaderWords)
|
self.leftForm.addRow(self.tr("Heading Words"), self.maxHeaderWords)
|
||||||
self.leftForm.addRow(self.tr("Body Text Words"), self.maxTextWords)
|
self.leftForm.addRow(self.tr("Body Text Words"), self.maxTextWords)
|
||||||
self.leftForm.addRow("", QLabel(self))
|
self.leftForm.addRow("", QLabel(self))
|
||||||
self.leftForm.addRow(self.tr("Headers"), self.maxTitleCount)
|
self.leftForm.addRow(self.tr("Headings"), self.maxTitleCount)
|
||||||
self.leftForm.addRow(self.tr("Paragraphs"), self.maxParCount)
|
self.leftForm.addRow(self.tr("Paragraphs"), self.maxParCount)
|
||||||
self.leftForm.setHorizontalSpacing(hPx)
|
self.leftForm.setHorizontalSpacing(hPx)
|
||||||
self.leftForm.setVerticalSpacing(vPx)
|
self.leftForm.setVerticalSpacing(vPx)
|
||||||
@@ -1038,10 +1038,10 @@ class _StatsWidget(QWidget):
|
|||||||
|
|
||||||
self.rightForm = QFormLayout()
|
self.rightForm = QFormLayout()
|
||||||
self.rightForm.addRow(self.tr("Characters"), self.maxTotalChars)
|
self.rightForm.addRow(self.tr("Characters"), self.maxTotalChars)
|
||||||
self.rightForm.addRow(self.tr("Header Characters"), self.maxHeaderChars)
|
self.rightForm.addRow(self.tr("Heading Characters"), self.maxHeaderChars)
|
||||||
self.rightForm.addRow(self.tr("Body Text Characters"), self.maxTextChars)
|
self.rightForm.addRow(self.tr("Body Text Characters"), self.maxTextChars)
|
||||||
self.rightForm.addRow(self.tr("Characters, No Spaces"), self.maxTotalWordChars)
|
self.rightForm.addRow(self.tr("Characters, No Spaces"), self.maxTotalWordChars)
|
||||||
self.rightForm.addRow(self.tr("Header Characters, No Spaces"), self.maxHeaderWordChars)
|
self.rightForm.addRow(self.tr("Heading Characters, No Spaces"), self.maxHeaderWordChars)
|
||||||
self.rightForm.addRow(self.tr("Body Text Characters, No Spaces"), self.maxTextWordChars)
|
self.rightForm.addRow(self.tr("Body Text Characters, No Spaces"), self.maxTextWordChars)
|
||||||
self.rightForm.setHorizontalSpacing(hPx)
|
self.rightForm.setHorizontalSpacing(hPx)
|
||||||
self.rightForm.setVerticalSpacing(vPx)
|
self.rightForm.setVerticalSpacing(vPx)
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ def testCoreIndex_CheckThese(mockGUI, fncPath, mockRnd):
|
|||||||
assert index._tagsIndex.tagHandle("Jane") == cHandle
|
assert index._tagsIndex.tagHandle("Jane") == cHandle
|
||||||
assert index._tagsIndex.tagHeading("Jane") == "T0001"
|
assert index._tagsIndex.tagHeading("Jane") == "T0001"
|
||||||
assert index._tagsIndex.tagClass("Jane") == "CHARACTER"
|
assert index._tagsIndex.tagClass("Jane") == "CHARACTER"
|
||||||
assert index.getItemHeader(nHandle, "T0001").title == "Hello World!" # type: ignore
|
assert index.getItemHeading(nHandle, "T0001").title == "Hello World!" # type: ignore
|
||||||
assert index.getReferences(nHandle, "T0001") == {
|
assert index.getReferences(nHandle, "T0001") == {
|
||||||
"@char": [],
|
"@char": [],
|
||||||
"@custom": [],
|
"@custom": [],
|
||||||
@@ -382,7 +382,7 @@ def testCoreIndex_ScanText(mockGUI, fncPath, mockRnd):
|
|||||||
assert index._tagsIndex.tagHandle("Jane") == cHandle
|
assert index._tagsIndex.tagHandle("Jane") == cHandle
|
||||||
assert index._tagsIndex.tagHeading("Jane") == "T0001"
|
assert index._tagsIndex.tagHeading("Jane") == "T0001"
|
||||||
assert index._tagsIndex.tagClass("Jane") == "CHARACTER"
|
assert index._tagsIndex.tagClass("Jane") == "CHARACTER"
|
||||||
assert index.getItemHeader(nHandle, "T0001").title == "Hello World!" # type: ignore
|
assert index.getItemHeading(nHandle, "T0001").title == "Hello World!" # type: ignore
|
||||||
|
|
||||||
# Title Indexing
|
# Title Indexing
|
||||||
# ==============
|
# ==============
|
||||||
@@ -560,8 +560,8 @@ def testCoreIndex_ExtractData(mockGUI, fncPath, mockRnd):
|
|||||||
assert isinstance(cHandle, str)
|
assert isinstance(cHandle, str)
|
||||||
assert isinstance(dHandle, str)
|
assert isinstance(dHandle, str)
|
||||||
|
|
||||||
assert index.getItemHeader("", "") is None
|
assert index.getItemHeading("", "") is None
|
||||||
assert index.getItemHeader(C.hNovelRoot, "") is None
|
assert index.getItemHeading(C.hNovelRoot, "") is None
|
||||||
|
|
||||||
assert index.scanText(cHandle, (
|
assert index.scanText(cHandle, (
|
||||||
"# Jane Smith\n"
|
"# Jane Smith\n"
|
||||||
@@ -685,11 +685,11 @@ def testCoreIndex_ExtractData(mockGUI, fncPath, mockRnd):
|
|||||||
assert list(index.getTagsData()) == [(
|
assert list(index.getTagsData()) == [(
|
||||||
"jane", "Jane", "CHARACTER",
|
"jane", "Jane", "CHARACTER",
|
||||||
index.getItemData(cHandle),
|
index.getItemData(cHandle),
|
||||||
index.getItemHeader(cHandle, "T0001")
|
index.getItemHeading(cHandle, "T0001")
|
||||||
), (
|
), (
|
||||||
"john", "John", "CHARACTER",
|
"john", "John", "CHARACTER",
|
||||||
index.getItemData(dHandle),
|
index.getItemData(dHandle),
|
||||||
index.getItemHeader(dHandle, "T0001")
|
index.getItemHeading(dHandle, "T0001")
|
||||||
)]
|
)]
|
||||||
|
|
||||||
# getSingleTag
|
# getSingleTag
|
||||||
@@ -697,7 +697,7 @@ def testCoreIndex_ExtractData(mockGUI, fncPath, mockRnd):
|
|||||||
assert index.getSingleTag("jane") == (
|
assert index.getSingleTag("jane") == (
|
||||||
"Jane", "CHARACTER",
|
"Jane", "CHARACTER",
|
||||||
index.getItemData(cHandle),
|
index.getItemData(cHandle),
|
||||||
index.getItemHeader(cHandle, "T0001")
|
index.getItemHeading(cHandle, "T0001")
|
||||||
)
|
)
|
||||||
assert index.getSingleTag("foobar") == ("", "", None, None)
|
assert index.getSingleTag("foobar") == ("", "", None, None)
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ def testCoreToHtml_ConvertHeaders(mockGUI):
|
|||||||
html._isNovel = False
|
html._isNovel = False
|
||||||
html._isNote = True
|
html._isNote = True
|
||||||
html._isFirst = True
|
html._isFirst = True
|
||||||
html.setLinkHeaders(True)
|
html.setLinkHeadings(True)
|
||||||
|
|
||||||
# Header 1
|
# Header 1
|
||||||
html._text = "# Heading One\n"
|
html._text = "# Heading One\n"
|
||||||
@@ -270,7 +270,7 @@ def testCoreToHtml_ConvertDirect(mockGUI):
|
|||||||
|
|
||||||
html._isNovel = True
|
html._isNovel = True
|
||||||
html._isNote = False
|
html._isNote = False
|
||||||
html.setLinkHeaders(True)
|
html.setLinkHeadings(True)
|
||||||
|
|
||||||
# Special Titles
|
# Special Titles
|
||||||
# ==============
|
# ==============
|
||||||
@@ -319,7 +319,7 @@ def testCoreToHtml_ConvertDirect(mockGUI):
|
|||||||
# Alignment
|
# Alignment
|
||||||
# =========
|
# =========
|
||||||
|
|
||||||
html.setLinkHeaders(False)
|
html.setLinkHeadings(False)
|
||||||
|
|
||||||
# Align Left
|
# Align Left
|
||||||
html.setStyles(False)
|
html.setStyles(False)
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ def testCoreToken_Setters(mockGUI):
|
|||||||
tokens.setHead4Margins(2.0, 2.0)
|
tokens.setHead4Margins(2.0, 2.0)
|
||||||
tokens.setTextMargins(2.0, 2.0)
|
tokens.setTextMargins(2.0, 2.0)
|
||||||
tokens.setMetaMargins(2.0, 2.0)
|
tokens.setMetaMargins(2.0, 2.0)
|
||||||
tokens.setLinkHeaders(True)
|
tokens.setLinkHeadings(True)
|
||||||
tokens.setBodyText(False)
|
tokens.setBodyText(False)
|
||||||
tokens.setSynopsis(True)
|
tokens.setSynopsis(True)
|
||||||
tokens.setComments(True)
|
tokens.setComments(True)
|
||||||
|
|||||||
@@ -1196,7 +1196,7 @@ def testGuiProjTree_ContextMenu(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
|||||||
actions = [x.text() for x in ctxMenu.actions() if x.text()]
|
actions = [x.text() for x in ctxMenu.actions() if x.text()]
|
||||||
assert actions == [
|
assert actions == [
|
||||||
"Create New ...", "Rename", "Set Status to ...", "Expand All",
|
"Create New ...", "Rename", "Set Status to ...", "Expand All",
|
||||||
"Collapse All", "Duplicate from Here", "Delete Permanently",
|
"Collapse All", "Duplicate", "Delete Permanently",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Context Menu on Folder Item
|
# Context Menu on Folder Item
|
||||||
@@ -1207,7 +1207,7 @@ def testGuiProjTree_ContextMenu(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
|||||||
actions = [x.text() for x in ctxMenu.actions() if x.text()]
|
actions = [x.text() for x in ctxMenu.actions() if x.text()]
|
||||||
assert actions == [
|
assert actions == [
|
||||||
"Create New ...", "Rename", "Set Status to ...", "Transform ...", "Expand All",
|
"Create New ...", "Rename", "Set Status to ...", "Transform ...", "Expand All",
|
||||||
"Collapse All", "Duplicate from Here", "Move to Trash",
|
"Collapse All", "Duplicate", "Move to Trash",
|
||||||
]
|
]
|
||||||
|
|
||||||
def getTransformSubMenu(menu: QMenu) -> list[str]:
|
def getTransformSubMenu(menu: QMenu) -> list[str]:
|
||||||
@@ -1225,11 +1225,11 @@ def testGuiProjTree_ContextMenu(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
|||||||
assert actions == [
|
assert actions == [
|
||||||
"Open Document", "View Document", "Create New ...", "Rename", "Rename to Heading",
|
"Open Document", "View Document", "Create New ...", "Rename", "Rename to Heading",
|
||||||
"Toggle Active", "Set Status to ...", "Transform ...", "Expand All", "Collapse All",
|
"Toggle Active", "Set Status to ...", "Transform ...", "Expand All", "Collapse All",
|
||||||
"Duplicate from Here", "Move to Trash",
|
"Duplicate", "Move to Trash",
|
||||||
]
|
]
|
||||||
assert getTransformSubMenu(ctxMenu) == [
|
assert getTransformSubMenu(ctxMenu) == [
|
||||||
"Convert to Project Note", "Merge Child Items into Self",
|
"Convert to Project Note", "Merge Child Items into Self",
|
||||||
"Merge Child Items into New", "Split Document by Headers"
|
"Merge Child Items into New", "Split Document by Headings"
|
||||||
]
|
]
|
||||||
|
|
||||||
# Context Menu on Note File Item in Character Folder
|
# Context Menu on Note File Item in Character Folder
|
||||||
@@ -1240,11 +1240,10 @@ def testGuiProjTree_ContextMenu(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
|||||||
actions = [x.text() for x in ctxMenu.actions() if x.text()]
|
actions = [x.text() for x in ctxMenu.actions() if x.text()]
|
||||||
assert actions == [
|
assert actions == [
|
||||||
"Open Document", "View Document", "Create New ...", "Rename", "Rename to Heading",
|
"Open Document", "View Document", "Create New ...", "Rename", "Rename to Heading",
|
||||||
"Toggle Active", "Set Importance to ...", "Transform ...", "Duplicate Document",
|
"Toggle Active", "Set Importance to ...", "Transform ...", "Duplicate", "Move to Trash",
|
||||||
"Move to Trash",
|
|
||||||
]
|
]
|
||||||
assert getTransformSubMenu(ctxMenu) == [
|
assert getTransformSubMenu(ctxMenu) == [
|
||||||
"Split Document by Headers",
|
"Split Document by Headings",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Context Menu on Note File Item in Novel Tree
|
# Context Menu on Note File Item in Novel Tree
|
||||||
@@ -1255,11 +1254,10 @@ def testGuiProjTree_ContextMenu(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
|||||||
actions = [x.text() for x in ctxMenu.actions() if x.text()]
|
actions = [x.text() for x in ctxMenu.actions() if x.text()]
|
||||||
assert actions == [
|
assert actions == [
|
||||||
"Open Document", "View Document", "Create New ...", "Rename", "Rename to Heading",
|
"Open Document", "View Document", "Create New ...", "Rename", "Rename to Heading",
|
||||||
"Toggle Active", "Set Status to ...", "Transform ...", "Duplicate Document",
|
"Toggle Active", "Set Status to ...", "Transform ...", "Duplicate", "Move to Trash",
|
||||||
"Move to Trash",
|
|
||||||
]
|
]
|
||||||
assert getTransformSubMenu(ctxMenu) == [
|
assert getTransformSubMenu(ctxMenu) == [
|
||||||
"Convert to Novel Document", "Split Document by Headers",
|
"Convert to Novel Document", "Split Document by Headings",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Context Menu on Multiple Items, Clicked on Document
|
# Context Menu on Multiple Items, Clicked on Document
|
||||||
|
|||||||
Reference in New Issue
Block a user