Use preview document class for manuscript preview
This commit is contained in:
@@ -99,7 +99,7 @@ class nwHeaders:
|
||||
|
||||
H_VALID = ("H0", "H1", "H2", "H3", "H4")
|
||||
H_LEVEL = {"H0": 0, "H1": 1, "H2": 2, "H3": 3, "H4": 4}
|
||||
H_SIZES = {0: 1.00, 1: 2.00, 2: 1.75, 3: 1.50, 4: 1.25}
|
||||
H_SIZES = {0: 2.50, 1: 2.00, 2: 1.75, 3: 1.50, 4: 1.25}
|
||||
|
||||
|
||||
class nwFiles:
|
||||
|
||||
@@ -39,6 +39,7 @@ from novelwriter.core.tohtml import ToHtml
|
||||
from novelwriter.core.tokenizer import Tokenizer
|
||||
from novelwriter.core.tomarkdown import ToMarkdown
|
||||
from novelwriter.core.toodt import ToOdt
|
||||
from novelwriter.core.toqdoc import TextDocumentTheme, ToQTextDocument
|
||||
from novelwriter.enum import nwBuildFmt
|
||||
from novelwriter.error import formatException, logException
|
||||
|
||||
@@ -134,6 +135,30 @@ class NWBuildDocument:
|
||||
self._queue.append(item.itemHandle)
|
||||
return
|
||||
|
||||
def iterBuildPreview(self, theme: TextDocumentTheme) -> Iterable[tuple[int, bool]]:
|
||||
"""Build a preview QTextDocument."""
|
||||
makeObj = ToQTextDocument(self._project)
|
||||
filtered = self._setupBuild(makeObj)
|
||||
|
||||
font = QFont()
|
||||
font.fromString(self._build.getStr("format.textFont"))
|
||||
|
||||
makeObj.setLinkHeadings(self._preview)
|
||||
makeObj.initDocument(font, theme)
|
||||
for i, tHandle in enumerate(self._queue):
|
||||
self._error = None
|
||||
if filtered.get(tHandle, (False, 0))[0]:
|
||||
yield i, self._doBuild(makeObj, tHandle)
|
||||
else:
|
||||
yield i, False
|
||||
|
||||
makeObj.appendFootnotes()
|
||||
|
||||
self._error = None
|
||||
self._cache = makeObj
|
||||
|
||||
return
|
||||
|
||||
def iterBuild(self, path: Path, bFormat: nwBuildFmt) -> Iterable[tuple[int, bool]]:
|
||||
"""Wrapper for builders based on format."""
|
||||
if bFormat in (nwBuildFmt.ODT, nwBuildFmt.FODT):
|
||||
|
||||
+77
-53
@@ -26,18 +26,17 @@ from __future__ import annotations
|
||||
import logging
|
||||
|
||||
from PyQt5.QtGui import (
|
||||
QFont, QFontMetrics, QTextBlockFormat, QTextCharFormat, QTextCursor,
|
||||
QTextDocument
|
||||
QColor, QFont, QFontMetrics, QTextBlockFormat, QTextCharFormat,
|
||||
QTextCursor, QTextDocument
|
||||
)
|
||||
|
||||
from novelwriter import SHARED
|
||||
from novelwriter.constants import nwHeaders, nwHeadFmt, nwKeyWords, nwLabels, nwUnicode
|
||||
from novelwriter.core.project import NWProject
|
||||
from novelwriter.core.tokenizer import T_Formats, Tokenizer
|
||||
from novelwriter.types import (
|
||||
QtAlignCenter, QtAlignJustify, QtAlignLeft, QtAlignRight, QtPageBreakAfter,
|
||||
QtPageBreakBefore, QtTransparent, QtVAlignNormal, QtVAlignSub,
|
||||
QtVAlignSuper
|
||||
QtAlignCenter, QtAlignJustify, QtAlignLeft, QtAlignRight, QtBlack,
|
||||
QtPageBreakAfter, QtPageBreakBefore, QtTransparent, QtVAlignNormal,
|
||||
QtVAlignSub, QtVAlignSuper
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -45,6 +44,19 @@ logger = logging.getLogger(__name__)
|
||||
T_TextStyle = tuple[QTextBlockFormat, QTextCharFormat]
|
||||
|
||||
|
||||
class TextDocumentTheme:
|
||||
text: QColor = QtBlack
|
||||
highlight: QColor = QtTransparent
|
||||
head: QColor = QtBlack
|
||||
comment: QColor = QtBlack
|
||||
note: QColor = QtBlack
|
||||
code: QColor = QtBlack
|
||||
modifier: QColor = QtBlack
|
||||
keyword: QColor = QtBlack
|
||||
tag: QColor = QtBlack
|
||||
optional: QColor = QtBlack
|
||||
|
||||
|
||||
def newBlock(cursor: QTextCursor, bFmt: QTextBlockFormat) -> None:
|
||||
if cursor.position() > 0:
|
||||
cursor.insertBlock(bFmt)
|
||||
@@ -64,6 +76,7 @@ class ToQTextDocument(Tokenizer):
|
||||
self._document = QTextDocument()
|
||||
self._document.setUndoRedoEnabled(False)
|
||||
|
||||
self._theme = TextDocumentTheme()
|
||||
self._styles: dict[int, T_TextStyle] = {}
|
||||
self._usedNotes: dict[str, int] = {}
|
||||
|
||||
@@ -73,9 +86,10 @@ class ToQTextDocument(Tokenizer):
|
||||
|
||||
return
|
||||
|
||||
def initDocument(self, font: QFont) -> None:
|
||||
def initDocument(self, font: QFont, theme: TextDocumentTheme) -> None:
|
||||
"""Initialise all computed values of the document."""
|
||||
self._textFont = font
|
||||
self._theme = theme
|
||||
|
||||
self._document.setUndoRedoEnabled(False)
|
||||
self._document.blockSignals(True)
|
||||
@@ -95,7 +109,7 @@ class ToQTextDocument(Tokenizer):
|
||||
}
|
||||
|
||||
self._sHead = {
|
||||
self.T_TITLE: nwHeaders.H_SIZES.get(1, 1.0) * fPt,
|
||||
self.T_TITLE: nwHeaders.H_SIZES.get(0, 1.0) * fPt,
|
||||
self.T_HEAD1: nwHeaders.H_SIZES.get(1, 1.0) * fPt,
|
||||
self.T_HEAD2: nwHeaders.H_SIZES.get(2, 1.0) * fPt,
|
||||
self.T_HEAD3: nwHeaders.H_SIZES.get(3, 1.0) * fPt,
|
||||
@@ -107,33 +121,41 @@ class ToQTextDocument(Tokenizer):
|
||||
|
||||
self._mIndent = mScale * 2.0
|
||||
|
||||
self._defaultChar = QTextCharFormat()
|
||||
self._defaultChar.setForeground(SHARED.theme.colText)
|
||||
self._cText = QTextCharFormat()
|
||||
self._cText.setForeground(self._theme.text)
|
||||
|
||||
self._comChar = QTextCharFormat()
|
||||
self._comChar.setForeground(SHARED.theme.colHidden)
|
||||
self._cHead = QTextCharFormat()
|
||||
self._cHead.setForeground(self._theme.head)
|
||||
|
||||
self._noteChar = QTextCharFormat()
|
||||
self._noteChar.setForeground(SHARED.theme.colNote)
|
||||
self._cComment = QTextCharFormat()
|
||||
self._cComment.setForeground(self._theme.comment)
|
||||
|
||||
self._codeChar = QTextCharFormat()
|
||||
self._codeChar.setForeground(SHARED.theme.colCode)
|
||||
self._cCommentMod = QTextCharFormat()
|
||||
self._cCommentMod.setForeground(self._theme.comment)
|
||||
self._cCommentMod.setFontWeight(self._bold)
|
||||
|
||||
self._modChar = QTextCharFormat()
|
||||
self._modChar.setForeground(SHARED.theme.colMod)
|
||||
self._cNote = QTextCharFormat()
|
||||
self._cNote.setForeground(self._theme.note)
|
||||
|
||||
self._keyChar = QTextCharFormat()
|
||||
self._keyChar.setForeground(SHARED.theme.colKey)
|
||||
self._cCode = QTextCharFormat()
|
||||
self._cCode.setForeground(self._theme.code)
|
||||
|
||||
self._tagChar = QTextCharFormat()
|
||||
self._tagChar.setForeground(SHARED.theme.colTag)
|
||||
self._cModifier = QTextCharFormat()
|
||||
self._cModifier.setForeground(self._theme.modifier)
|
||||
self._cModifier.setFontWeight(self._bold)
|
||||
|
||||
self._optChar = QTextCharFormat()
|
||||
self._optChar.setForeground(SHARED.theme.colOpt)
|
||||
self._cKeyword = QTextCharFormat()
|
||||
self._cKeyword.setForeground(self._theme.keyword)
|
||||
|
||||
self._defaultBlock = QTextBlockFormat()
|
||||
self._defaultBlock.setTopMargin(self._mText[0])
|
||||
self._defaultBlock.setBottomMargin(self._mText[1])
|
||||
self._cTag = QTextCharFormat()
|
||||
self._cTag.setForeground(self._theme.tag)
|
||||
|
||||
self._cOptional = QTextCharFormat()
|
||||
self._cOptional.setForeground(self._theme.optional)
|
||||
|
||||
self._blockFmt = QTextBlockFormat()
|
||||
self._blockFmt.setTopMargin(self._mText[0])
|
||||
self._blockFmt.setBottomMargin(self._mText[1])
|
||||
|
||||
self._init = True
|
||||
|
||||
@@ -159,11 +181,12 @@ class ToQTextDocument(Tokenizer):
|
||||
|
||||
self._document.blockSignals(True)
|
||||
cursor = QTextCursor(self._document)
|
||||
cursor.movePosition(QTextCursor.MoveOperation.End)
|
||||
|
||||
for tType, nHead, tText, tFormat, tStyle in self._tokens:
|
||||
|
||||
# Styles
|
||||
bFmt = QTextBlockFormat(self._defaultBlock)
|
||||
bFmt = QTextBlockFormat(self._blockFmt)
|
||||
if tStyle is not None:
|
||||
if tStyle & self.A_LEFT:
|
||||
bFmt.setAlignment(QtAlignLeft)
|
||||
@@ -191,7 +214,7 @@ class ToQTextDocument(Tokenizer):
|
||||
|
||||
if tType == self.T_TEXT:
|
||||
newBlock(cursor, bFmt)
|
||||
self._insertFragments(tText, tFormat, cursor, self._defaultChar)
|
||||
self._insertFragments(tText, tFormat, cursor, self._cText)
|
||||
|
||||
elif tType in self.L_HEADINGS:
|
||||
bFmt, cFmt = self._genHeadStyle(tType, nHead, bFmt)
|
||||
@@ -200,23 +223,25 @@ class ToQTextDocument(Tokenizer):
|
||||
|
||||
elif tType == self.T_SEP:
|
||||
newBlock(cursor, bFmt)
|
||||
cursor.insertText(tText, self._defaultChar)
|
||||
cursor.insertText(tText, self._cText)
|
||||
|
||||
elif tType == self.T_SKIP:
|
||||
newBlock(cursor, bFmt)
|
||||
cursor.insertText(nwUnicode.U_NBSP, self._defaultChar)
|
||||
cursor.insertText(nwUnicode.U_NBSP, self._cText)
|
||||
|
||||
elif tType in self.L_SUMMARY and self._doSynopsis:
|
||||
newBlock(cursor, bFmt)
|
||||
prefix = self._localLookup(
|
||||
modifier = self._localLookup(
|
||||
"Short Description" if tType == self.T_SHORT else "Synopsis"
|
||||
)
|
||||
cursor.insertText(f"{prefix}: ", self._modChar)
|
||||
self._insertFragments(tText, tFormat, cursor, self._noteChar)
|
||||
cursor.insertText(f"{modifier}: ", self._cModifier)
|
||||
self._insertFragments(tText, tFormat, cursor, self._cNote)
|
||||
|
||||
elif tType == self.T_COMMENT and self._doComments:
|
||||
newBlock(cursor, bFmt)
|
||||
self._insertFragments(tText, tFormat, cursor, self._comChar)
|
||||
modifier = self._localLookup("Comment")
|
||||
cursor.insertText(f"{modifier}: ", self._cCommentMod)
|
||||
self._insertFragments(tText, tFormat, cursor, self._cComment)
|
||||
|
||||
elif tType == self.T_KEYWORD and self._doKeywords:
|
||||
newBlock(cursor, bFmt)
|
||||
@@ -234,18 +259,18 @@ class ToQTextDocument(Tokenizer):
|
||||
cursor = QTextCursor(self._document)
|
||||
cursor.movePosition(QTextCursor.MoveOperation.End)
|
||||
|
||||
bFmt, cFmt = self._genHeadStyle(self.T_HEAD3, -1, self._defaultBlock)
|
||||
bFmt, cFmt = self._genHeadStyle(self.T_HEAD3, -1, self._blockFmt)
|
||||
newBlock(cursor, bFmt)
|
||||
cursor.insertText(self._localLookup("Footnotes"), cFmt)
|
||||
|
||||
for key, index in self._usedNotes.items():
|
||||
if content := self._footnotes.get(key):
|
||||
cFmt = QTextCharFormat(self._codeChar)
|
||||
cFmt = QTextCharFormat(self._cCode)
|
||||
cFmt.setAnchor(True)
|
||||
cFmt.setAnchorNames([f"footnote_{index}"])
|
||||
newBlock(cursor, self._defaultBlock)
|
||||
newBlock(cursor, self._blockFmt)
|
||||
cursor.insertText(f"{index}. ", cFmt)
|
||||
self._insertFragments(*content, cursor, self._defaultChar)
|
||||
self._insertFragments(*content, cursor, self._cText)
|
||||
|
||||
self._document.blockSignals(False)
|
||||
|
||||
@@ -285,7 +310,7 @@ class ToQTextDocument(Tokenizer):
|
||||
elif fmt == self.FMT_U_E:
|
||||
cFmt.setFontUnderline(False)
|
||||
elif fmt == self.FMT_M_B:
|
||||
cFmt.setBackground(SHARED.theme.colMark)
|
||||
cFmt.setBackground(self._theme.highlight)
|
||||
elif fmt == self.FMT_M_E:
|
||||
cFmt.setBackground(QtTransparent)
|
||||
elif fmt == self.FMT_SUP_B:
|
||||
@@ -297,7 +322,7 @@ class ToQTextDocument(Tokenizer):
|
||||
elif fmt == self.FMT_SUB_E:
|
||||
cFmt.setVerticalAlignment(QtVAlignNormal)
|
||||
elif fmt == self.FMT_FNOTE:
|
||||
xFmt = QTextCharFormat(self._codeChar)
|
||||
xFmt = QTextCharFormat(self._cCode)
|
||||
xFmt.setVerticalAlignment(QtVAlignSuper)
|
||||
if data in self._footnotes:
|
||||
index = len(self._usedNotes) + 1
|
||||
@@ -322,37 +347,36 @@ class ToQTextDocument(Tokenizer):
|
||||
valid, bits, _ = self._project.index.scanThis("@"+text)
|
||||
if valid and bits:
|
||||
key = f"{self._localLookup(nwLabels.KEY_NAME[bits[0]])}: "
|
||||
cursor.insertText(key, self._keyChar)
|
||||
cursor.insertText(key, self._cKeyword)
|
||||
if (num := len(bits)) > 1:
|
||||
if bits[0] == nwKeyWords.TAG_KEY:
|
||||
one, two = self._project.index.parseValue(bits[1])
|
||||
cursor.insertText(one, self._tagChar)
|
||||
cursor.insertText(one, self._cTag)
|
||||
if two:
|
||||
cursor.insertText(" | ", self._defaultChar)
|
||||
cursor.insertText(two, self._optChar)
|
||||
cursor.insertText(" | ", self._cText)
|
||||
cursor.insertText(two, self._cOptional)
|
||||
else:
|
||||
for n, bit in enumerate(bits[1:], 2):
|
||||
cFmt = QTextCharFormat(self._tagChar)
|
||||
cFmt = QTextCharFormat(self._cTag)
|
||||
cFmt.setFontUnderline(True)
|
||||
cFmt.setAnchor(True)
|
||||
cFmt.setAnchorHref(f"#{bits[0][1:]}={bit}")
|
||||
cursor.insertText(bit, cFmt)
|
||||
if n < num:
|
||||
cursor.insertText(", ", self._defaultChar)
|
||||
cursor.insertText(", ", self._cText)
|
||||
return
|
||||
|
||||
def _genHeadStyle(self, level: int, nHead: int, rFmt: QTextBlockFormat) -> T_TextStyle:
|
||||
def _genHeadStyle(self, hType: int, nHead: int, rFmt: QTextBlockFormat) -> T_TextStyle:
|
||||
"""Generate a heading style set."""
|
||||
mTop, mBottom = self._mHead.get(level, (0.0, 0.0))
|
||||
mTop, mBottom = self._mHead.get(hType, (0.0, 0.0))
|
||||
|
||||
bFmt = QTextBlockFormat(rFmt)
|
||||
bFmt.setTopMargin(mTop)
|
||||
bFmt.setBottomMargin(mBottom)
|
||||
|
||||
cFmt = QTextCharFormat(self._defaultChar)
|
||||
cFmt.setForeground(SHARED.theme.colHead)
|
||||
cFmt.setFontWeight(QFont.Weight.Bold)
|
||||
cFmt.setFontPointSize(self._sHead.get(level, 1.0))
|
||||
cFmt = QTextCharFormat(self._cText if hType == self.T_TITLE else self._cHead)
|
||||
cFmt.setFontWeight(self._bold)
|
||||
cFmt.setFontPointSize(self._sHead.get(hType, 1.0))
|
||||
if nHead >= 0:
|
||||
cFmt.setAnchorNames([f"{self._handle}:T{nHead:04d}"])
|
||||
cFmt.setAnchor(True)
|
||||
|
||||
@@ -40,7 +40,7 @@ from PyQt5.QtWidgets import (
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.common import cssCol
|
||||
from novelwriter.constants import nwHeaders, nwUnicode
|
||||
from novelwriter.core.toqdoc import ToQTextDocument
|
||||
from novelwriter.core.toqdoc import TextDocumentTheme, ToQTextDocument
|
||||
from novelwriter.enum import nwDocAction, nwDocMode, nwItemType
|
||||
from novelwriter.error import logException
|
||||
from novelwriter.extensions.eventfilters import WheelEventFilter
|
||||
@@ -69,6 +69,7 @@ class GuiDocViewer(QTextBrowser):
|
||||
|
||||
# Internal Variables
|
||||
self._docHandle = None
|
||||
self._docTheme = TextDocumentTheme()
|
||||
|
||||
# Settings
|
||||
self.setMinimumWidth(CONFIG.pxInt(300))
|
||||
@@ -152,6 +153,17 @@ class GuiDocViewer(QTextBrowser):
|
||||
docPalette.setColor(QPalette.ColorRole.Text, SHARED.theme.colText)
|
||||
self.viewport().setPalette(docPalette)
|
||||
|
||||
self._docTheme.text = SHARED.theme.colText
|
||||
self._docTheme.highlight = SHARED.theme.colMark
|
||||
self._docTheme.head = SHARED.theme.colHead
|
||||
self._docTheme.comment = SHARED.theme.colHidden
|
||||
self._docTheme.note = SHARED.theme.colNote
|
||||
self._docTheme.code = SHARED.theme.colCode
|
||||
self._docTheme.modifier = SHARED.theme.colMod
|
||||
self._docTheme.keyword = SHARED.theme.colKey
|
||||
self._docTheme.tag = SHARED.theme.colTag
|
||||
self._docTheme.optional = SHARED.theme.colOpt
|
||||
|
||||
self.docHeader.matchColours()
|
||||
self.docFooter.matchColours()
|
||||
|
||||
@@ -203,11 +215,10 @@ class GuiDocViewer(QTextBrowser):
|
||||
|
||||
sPos = self.verticalScrollBar().value()
|
||||
qDoc = ToQTextDocument(SHARED.project)
|
||||
qDoc.initDocument(CONFIG.textFont)
|
||||
qDoc.initDocument(CONFIG.textFont, self._docTheme)
|
||||
qDoc.setKeywords(True)
|
||||
qDoc.setComments(CONFIG.viewComments)
|
||||
qDoc.setSynopsis(CONFIG.viewSynopsis)
|
||||
qDoc.setLinkHeadings(True)
|
||||
|
||||
# Be extra careful here to prevent crashes when first opening a
|
||||
# project as a crash here leaves no way of recovering.
|
||||
|
||||
@@ -31,7 +31,7 @@ from time import time
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from PyQt5.QtCore import Qt, QTimer, QUrl, pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtGui import QCloseEvent, QColor, QCursor, QFont, QPalette, QResizeEvent
|
||||
from PyQt5.QtGui import QCloseEvent, QColor, QCursor, QFont, QPalette, QResizeEvent, QTextDocument
|
||||
from PyQt5.QtPrintSupport import QPrinter, QPrintPreviewDialog
|
||||
from PyQt5.QtWidgets import (
|
||||
QAbstractItemView, QApplication, QFormLayout, QGridLayout, QHBoxLayout,
|
||||
@@ -44,8 +44,8 @@ from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.common import checkInt, fuzzyTime
|
||||
from novelwriter.core.buildsettings import BuildCollection, BuildSettings
|
||||
from novelwriter.core.docbuild import NWBuildDocument
|
||||
from novelwriter.core.tohtml import ToHtml
|
||||
from novelwriter.core.tokenizer import HeadingFormatter
|
||||
from novelwriter.core.toqdoc import TextDocumentTheme, ToQTextDocument
|
||||
from novelwriter.error import logException
|
||||
from novelwriter.extensions.circularprogress import NProgressCircle
|
||||
from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton, NToolDialog
|
||||
@@ -250,19 +250,19 @@ class GuiManuscript(NToolDialog):
|
||||
if selected in self._buildMap:
|
||||
self.buildList.setCurrentItem(self._buildMap[selected])
|
||||
|
||||
logger.debug("Loading build cache")
|
||||
cache = CONFIG.dataPath("cache") / f"build_{SHARED.project.data.uuid}.json"
|
||||
if cache.is_file():
|
||||
try:
|
||||
with open(cache, mode="r", encoding="utf-8") as fObj:
|
||||
data = json.load(fObj)
|
||||
build = self._builds.getBuild(data.get("uuid", ""))
|
||||
if isinstance(build, BuildSettings):
|
||||
self._updatePreview(data, build)
|
||||
except Exception:
|
||||
logger.error("Failed to load build cache")
|
||||
logException()
|
||||
return
|
||||
# logger.debug("Loading build cache")
|
||||
# cache = CONFIG.dataPath("cache") / f"build_{SHARED.project.data.uuid}.json"
|
||||
# if cache.is_file():
|
||||
# try:
|
||||
# with open(cache, mode="r", encoding="utf-8") as fObj:
|
||||
# data = json.load(fObj)
|
||||
# build = self._builds.getBuild(data.get("uuid", ""))
|
||||
# if isinstance(build, BuildSettings):
|
||||
# self._updatePreview(data, build)
|
||||
# except Exception:
|
||||
# logger.error("Failed to load build cache")
|
||||
# logException()
|
||||
# return
|
||||
|
||||
return
|
||||
|
||||
@@ -345,29 +345,38 @@ class GuiManuscript(NToolDialog):
|
||||
docBuild.setPreviewMode(True)
|
||||
docBuild.queueAll()
|
||||
|
||||
theme = TextDocumentTheme()
|
||||
theme.text = QColor(0, 0, 0)
|
||||
theme.highlight = QColor(255, 255, 166)
|
||||
theme.head = QColor(66, 113, 174)
|
||||
theme.comment = QColor(100, 100, 100)
|
||||
theme.note = QColor(129, 55, 9)
|
||||
theme.code = QColor(66, 113, 174)
|
||||
theme.modifier = QColor(129, 55, 9)
|
||||
theme.keyword = QColor(245, 135, 31)
|
||||
theme.tag = QColor(66, 113, 174)
|
||||
theme.optional = QColor(66, 113, 174)
|
||||
|
||||
self.docPreview.beginNewBuild(len(docBuild))
|
||||
for step, _ in docBuild.iterBuildHTML(None):
|
||||
for step, _ in docBuild.iterBuildPreview(theme):
|
||||
self.docPreview.buildStep(step + 1)
|
||||
QApplication.processEvents()
|
||||
|
||||
buildObj = docBuild.lastBuild
|
||||
assert isinstance(buildObj, ToHtml)
|
||||
result = {
|
||||
assert isinstance(buildObj, ToQTextDocument)
|
||||
data = {
|
||||
"uuid": build.buildID,
|
||||
"time": int(time()),
|
||||
"stats": buildObj.textStats,
|
||||
"outline": buildObj.textOutline,
|
||||
"styles": buildObj.getStyleSheet(),
|
||||
"html": buildObj.fullHTML,
|
||||
}
|
||||
|
||||
self._updatePreview(result, build)
|
||||
self._updatePreview(data, build, buildObj.document)
|
||||
|
||||
logger.debug("Saving build cache")
|
||||
cache = CONFIG.dataPath("cache") / f"build_{SHARED.project.data.uuid}.json"
|
||||
try:
|
||||
with open(cache, mode="w+", encoding="utf-8") as outFile:
|
||||
outFile.write(json.dumps(result, indent=2))
|
||||
outFile.write(json.dumps(data, indent=2))
|
||||
except Exception:
|
||||
logger.error("Failed to save build cache")
|
||||
logException()
|
||||
@@ -400,17 +409,14 @@ class GuiManuscript(NToolDialog):
|
||||
# Internal Functions
|
||||
##
|
||||
|
||||
def _updatePreview(self, data: dict, build: BuildSettings) -> None:
|
||||
def _updatePreview(self, data: dict, build: BuildSettings, document: QTextDocument) -> None:
|
||||
"""Update the preview widget and set relevant values."""
|
||||
textFont = QFont()
|
||||
textFont.fromString(build.getStr("format.textFont"))
|
||||
|
||||
self.docPreview.setContent(data)
|
||||
font = QFont()
|
||||
font.fromString(build.getStr("format.textFont"))
|
||||
self.docPreview.setTextFont(font)
|
||||
self.docPreview.setContent(data, document)
|
||||
self.docPreview.setBuildName(build.name)
|
||||
self.docPreview.setTextFont(textFont)
|
||||
self.docPreview.setJustify(
|
||||
build.getBool("format.justifyText")
|
||||
)
|
||||
self.docPreview.setJustify(build.getBool("format.justifyText"))
|
||||
self.docStats.updateStats(data.get("stats", {}))
|
||||
self.buildOutline.updateOutline(data.get("outline", {}))
|
||||
return
|
||||
@@ -848,30 +854,22 @@ class _PreviewWidget(QTextBrowser):
|
||||
QApplication.processEvents()
|
||||
return
|
||||
|
||||
def setContent(self, data: dict) -> None:
|
||||
def setContent(self, data: dict, doc: QTextDocument) -> None:
|
||||
"""Set the content of the preview widget."""
|
||||
QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
||||
|
||||
self.buildProgress.setCentreText(self.tr("Processing ..."))
|
||||
QApplication.processEvents()
|
||||
|
||||
styles = "\n".join(data.get("styles", []))
|
||||
self.document().setDefaultStyleSheet(styles)
|
||||
|
||||
html = "".join(data.get("html", []))
|
||||
html = html.replace("\t", "!!tab!!")
|
||||
self.setHtml(html)
|
||||
QApplication.processEvents()
|
||||
while self.find("!!tab!!"):
|
||||
cursor = self.textCursor()
|
||||
cursor.insertText("\t")
|
||||
doc.setDocumentMargin(CONFIG.getTextMargin())
|
||||
self.setDocument(doc)
|
||||
|
||||
self._docTime = checkInt(data.get("time"), 0)
|
||||
self._updateBuildAge()
|
||||
|
||||
# Since we change the content while it may still be rendering, we mark
|
||||
# the document as dirty again to make sure it's re-rendered properly.
|
||||
self.document().markContentsDirty(0, self.document().characterCount())
|
||||
# self.document().markContentsDirty(0, self.document().characterCount())
|
||||
|
||||
self.buildProgress.setCentreText(self.tr("Done"))
|
||||
QApplication.restoreOverrideCursor()
|
||||
|
||||
@@ -56,6 +56,7 @@ QtPageBreakAfter = QTextFormat.PageBreakFlag.PageBreak_AlwaysAfter
|
||||
# Qt Painter Types
|
||||
|
||||
QtTransparent = QColor(0, 0, 0, 0)
|
||||
QtBlack = QColor(0, 0, 0)
|
||||
QtNoBrush = Qt.BrushStyle.NoBrush
|
||||
QtNoPen = Qt.PenStyle.NoPen
|
||||
QtRoundCap = Qt.PenCapStyle.RoundCap
|
||||
|
||||
Reference in New Issue
Block a user