Refactor Odt paragraph class further

This commit is contained in:
Veronica Berglyd Olsen
2024-04-05 17:49:16 +02:00
parent 5b8212f2fa
commit f7736b87bb
2 changed files with 114 additions and 91 deletions
+101 -80
View File
@@ -406,7 +406,7 @@ class ToOdt(Tokenizer):
for tType, _, tText, tFormat, tStyle in self._tokens: for tType, _, tText, tFormat, tStyle in self._tokens:
# Styles # Styles
oStyle = ODTParagraphStyle() oStyle = ODTParagraphStyle("New")
if tStyle is not None: if tStyle is not None:
if tStyle & self.A_LEFT: if tStyle & self.A_LEFT:
oStyle.setTextAlign("left") oStyle.setTextAlign("left")
@@ -686,26 +686,27 @@ class ToOdt(Tokenizer):
return return
def _paraStyle(self, parName: str, oStyle: ODTParagraphStyle) -> str: def _paraStyle(self, mainName: str, modStyle: ODTParagraphStyle) -> str:
"""Return a name for a style object.""" """Return a name for a style object."""
refStyle = self._mainPara.get(parName, None) if not (refStyle := self._mainPara.get(mainName, None)):
if refStyle is None: logger.error("Unknown main paragraph style '%s'", mainName)
logger.error("Unknown paragraph style '%s'", parName)
return "Standard" return "Standard"
if not refStyle.checkNew(oStyle): if not refStyle.checkNew(modStyle):
return parName # The style is unmodified, so we return the main style
return mainName
oStyle.setParentStyleName(parName) # The style is modified, so we check if there already is an
pID = oStyle.getID() # identical style with the same parent we can use instead
if pID in self._autoPara: modStyle.setParentStyleName(mainName)
if (pID := modStyle.getID()) in self._autoPara:
return self._autoPara[pID].name return self._autoPara[pID].name
name = f"P{len(self._autoPara)+1:d}" # If neither of the above hold, we store it as a new style
oStyle.setName(name) modStyle.setName(f"P{len(self._autoPara)+1:d}")
self._autoPara[pID] = oStyle self._autoPara[pID] = modStyle
return name return modStyle.name
def _textStyle(self, hFmt: int) -> str: def _textStyle(self, hFmt: int) -> str:
"""Return a text style for a given style code.""" """Return a text style for a given style code."""
@@ -834,145 +835,145 @@ class ToOdt(Tokenizer):
"""Set the usable styles.""" """Set the usable styles."""
# Add Text Body Style # Add Text Body Style
style = ODTParagraphStyle("Text_20_body") style = ODTParagraphStyle("Text_20_body")
style.setClass("text")
style.setDisplayName("Text body") style.setDisplayName("Text body")
style.setFontFamily(self._fontFamily)
style.setFontName(self._textFont)
style.setFontSize(self._fSizeText)
style.setLineHeight(self._fLineHeight)
style.setMarginBottom(self._mBotText)
style.setMarginTop(self._mTopText)
style.setParentStyleName("Standard") style.setParentStyleName("Standard")
style.setClass("text")
style.setMarginTop(self._mTopText)
style.setMarginBottom(self._mBotText)
style.setLineHeight(self._fLineHeight)
style.setTextAlign(self._textAlign) style.setTextAlign(self._textAlign)
style.setFontName(self._textFont)
style.setFontFamily(self._fontFamily)
style.setFontSize(self._fSizeText)
style.packXML(self._xStyl) style.packXML(self._xStyl)
self._mainPara[style.name] = style self._mainPara[style.name] = style
# Add First Line Indent Style # Add First Line Indent Style
style = ODTParagraphStyle("First_20_line_20_indent") style = ODTParagraphStyle("First_20_line_20_indent")
style.setClass("text")
style.setDisplayName("First line indent") style.setDisplayName("First line indent")
style.setParentStyleName("Text_20_body") style.setParentStyleName("Text_20_body")
style.setClass("text")
style.setTextIndent(self._fTextIndent) style.setTextIndent(self._fTextIndent)
style.packXML(self._xStyl) style.packXML(self._xStyl)
self._mainPara[style.name] = style self._mainPara[style.name] = style
# Add Text Meta Style # Add Text Meta Style
style = ODTParagraphStyle("Text_20_Meta") style = ODTParagraphStyle("Text_20_Meta")
style.setClass("text")
style.setColor(self._colMetaTx)
style.setDisplayName("Text Meta") style.setDisplayName("Text Meta")
style.setFontFamily(self._fontFamily)
style.setFontName(self._textFont)
style.setFontSize(self._fSizeText)
style.setLineHeight(self._fLineHeight)
style.setMarginBottom(self._mBotMeta)
style.setMarginTop(self._mTopMeta)
style.setOpacity(self._opaMetaTx)
style.setParentStyleName("Standard") style.setParentStyleName("Standard")
style.setClass("text")
style.setMarginTop(self._mTopMeta)
style.setMarginBottom(self._mBotMeta)
style.setLineHeight(self._fLineHeight)
style.setFontName(self._textFont)
style.setFontFamily(self._fontFamily)
style.setFontSize(self._fSizeText)
style.setColour(self._colMetaTx)
style.setOpacity(self._opaMetaTx)
style.packXML(self._xStyl) style.packXML(self._xStyl)
self._mainPara[style.name] = style self._mainPara[style.name] = style
# Add Title Style # Add Title Style
style = ODTParagraphStyle("Title") style = ODTParagraphStyle("Title")
style.setClass("chapter")
style.setDisplayName("Title") style.setDisplayName("Title")
style.setFontFamily(self._fontFamily) style.setParentStyleName("Heading")
style.setNextStyleName("Text_20_body")
style.setClass("chapter")
style.setMarginTop(self._mTopTitle)
style.setMarginBottom(self._mBotTitle)
style.setTextAlign("center")
style.setFontName(self._textFont) style.setFontName(self._textFont)
style.setFontFamily(self._fontFamily)
style.setFontSize(self._fSizeTitle) style.setFontSize(self._fSizeTitle)
style.setFontWeight("bold") style.setFontWeight("bold")
style.setMarginBottom(self._mBotTitle)
style.setMarginTop(self._mTopTitle)
style.setNextStyleName("Text_20_body")
style.setParentStyleName("Heading")
style.setTextAlign("center")
style.packXML(self._xStyl) style.packXML(self._xStyl)
self._mainPara[style.name] = style self._mainPara[style.name] = style
# Add Separator Style # Add Separator Style
style = ODTParagraphStyle("Separator") style = ODTParagraphStyle("Separator")
style.setClass("text")
style.setDisplayName("Separator") style.setDisplayName("Separator")
style.setFontFamily(self._fontFamily)
style.setFontName(self._textFont)
style.setFontSize(self._fSizeText)
style.setLineHeight(self._fLineHeight)
style.setMarginBottom(self._mBotText)
style.setMarginTop(self._mTopText)
style.setNextStyleName("Text_20_body")
style.setParentStyleName("Standard") style.setParentStyleName("Standard")
style.setNextStyleName("Text_20_body")
style.setClass("text")
style.setMarginTop(self._mTopText)
style.setMarginBottom(self._mBotText)
style.setLineHeight(self._fLineHeight)
style.setTextAlign("center") style.setTextAlign("center")
style.setFontName(self._textFont)
style.setFontFamily(self._fontFamily)
style.setFontSize(self._fSizeText)
style.packXML(self._xStyl) style.packXML(self._xStyl)
self._mainPara[style.name] = style self._mainPara[style.name] = style
# Add Heading 1 Style # Add Heading 1 Style
style = ODTParagraphStyle("Heading_20_1") style = ODTParagraphStyle("Heading_20_1")
style.setClass("text")
style.setColor(self._colHead12)
style.setDisplayName("Heading 1") style.setDisplayName("Heading 1")
style.setFontFamily(self._fontFamily) style.setParentStyleName("Heading")
style.setNextStyleName("Text_20_body")
style.setOutlineLevel("1")
style.setClass("text")
style.setMarginTop(self._mTopHead1)
style.setMarginBottom(self._mBotHead1)
style.setFontName(self._textFont) style.setFontName(self._textFont)
style.setFontFamily(self._fontFamily)
style.setFontSize(self._fSizeHead1) style.setFontSize(self._fSizeHead1)
style.setFontWeight("bold") style.setFontWeight("bold")
style.setMarginBottom(self._mBotHead1) style.setColour(self._colHead12)
style.setMarginTop(self._mTopHead1)
style.setNextStyleName("Text_20_body")
style.setOpacity(self._opaHead12) style.setOpacity(self._opaHead12)
style.setOutlineLevel("1")
style.setParentStyleName("Heading")
style.packXML(self._xStyl) style.packXML(self._xStyl)
self._mainPara[style.name] = style self._mainPara[style.name] = style
# Add Heading 2 Style # Add Heading 2 Style
style = ODTParagraphStyle("Heading_20_2") style = ODTParagraphStyle("Heading_20_2")
style.setClass("text")
style.setColor(self._colHead12)
style.setDisplayName("Heading 2") style.setDisplayName("Heading 2")
style.setFontFamily(self._fontFamily) style.setParentStyleName("Heading")
style.setNextStyleName("Text_20_body")
style.setOutlineLevel("2")
style.setClass("text")
style.setMarginTop(self._mTopHead2)
style.setMarginBottom(self._mBotHead2)
style.setFontName(self._textFont) style.setFontName(self._textFont)
style.setFontFamily(self._fontFamily)
style.setFontSize(self._fSizeHead2) style.setFontSize(self._fSizeHead2)
style.setFontWeight("bold") style.setFontWeight("bold")
style.setMarginBottom(self._mBotHead2) style.setColour(self._colHead12)
style.setMarginTop(self._mTopHead2)
style.setNextStyleName("Text_20_body")
style.setOpacity(self._opaHead12) style.setOpacity(self._opaHead12)
style.setOutlineLevel("2")
style.setParentStyleName("Heading")
style.packXML(self._xStyl) style.packXML(self._xStyl)
self._mainPara[style.name] = style self._mainPara[style.name] = style
# Add Heading 3 Style # Add Heading 3 Style
style = ODTParagraphStyle("Heading_20_3") style = ODTParagraphStyle("Heading_20_3")
style.setClass("text")
style.setColor(self._colHead34)
style.setDisplayName("Heading 3") style.setDisplayName("Heading 3")
style.setFontFamily(self._fontFamily) style.setParentStyleName("Heading")
style.setNextStyleName("Text_20_body")
style.setOutlineLevel("3")
style.setClass("text")
style.setMarginTop(self._mTopHead3)
style.setMarginBottom(self._mBotHead3)
style.setFontName(self._textFont) style.setFontName(self._textFont)
style.setFontFamily(self._fontFamily)
style.setFontSize(self._fSizeHead3) style.setFontSize(self._fSizeHead3)
style.setFontWeight("bold") style.setFontWeight("bold")
style.setMarginBottom(self._mBotHead3) style.setColour(self._colHead34)
style.setMarginTop(self._mTopHead3)
style.setNextStyleName("Text_20_body")
style.setOpacity(self._opaHead34) style.setOpacity(self._opaHead34)
style.setOutlineLevel("3")
style.setParentStyleName("Heading")
style.packXML(self._xStyl) style.packXML(self._xStyl)
self._mainPara[style.name] = style self._mainPara[style.name] = style
# Add Heading 4 Style # Add Heading 4 Style
style = ODTParagraphStyle("Heading_20_4") style = ODTParagraphStyle("Heading_20_4")
style.setClass("text")
style.setColor(self._colHead34)
style.setDisplayName("Heading 4") style.setDisplayName("Heading 4")
style.setFontFamily(self._fontFamily) style.setParentStyleName("Heading")
style.setNextStyleName("Text_20_body")
style.setOutlineLevel("4")
style.setClass("text")
style.setMarginTop(self._mTopHead4)
style.setMarginBottom(self._mBotHead4)
style.setFontName(self._textFont) style.setFontName(self._textFont)
style.setFontFamily(self._fontFamily)
style.setFontSize(self._fSizeHead4) style.setFontSize(self._fSizeHead4)
style.setFontWeight("bold") style.setFontWeight("bold")
style.setMarginBottom(self._mBotHead4) style.setColour(self._colHead34)
style.setMarginTop(self._mTopHead4)
style.setNextStyleName("Text_20_body")
style.setOpacity(self._opaHead34) style.setOpacity(self._opaHead34)
style.setOutlineLevel("4")
style.setParentStyleName("Heading")
style.packXML(self._xStyl) style.packXML(self._xStyl)
self._mainPara[style.name] = style self._mainPara[style.name] = style
@@ -1043,7 +1044,7 @@ class ODTParagraphStyle:
VALID_CLASS = ["text", "chapter"] VALID_CLASS = ["text", "chapter"]
VALID_WEIGHT = ["normal", "inherit", "bold"] VALID_WEIGHT = ["normal", "inherit", "bold"]
def __init__(self, name: str = "None") -> None: def __init__(self, name: str) -> None:
self._name = name self._name = name
@@ -1109,18 +1110,22 @@ class ODTParagraphStyle:
## ##
def setDisplayName(self, value: str | None) -> None: def setDisplayName(self, value: str | None) -> None:
"""Set style display name."""
self._mAttr["display-name"][1] = value self._mAttr["display-name"][1] = value
return return
def setParentStyleName(self, value: str | None) -> None: def setParentStyleName(self, value: str | None) -> None:
"""Set parent style name."""
self._mAttr["parent-style-name"][1] = value self._mAttr["parent-style-name"][1] = value
return return
def setNextStyleName(self, value: str | None) -> None: def setNextStyleName(self, value: str | None) -> None:
"""Set next style name."""
self._mAttr["next-style-name"][1] = value self._mAttr["next-style-name"][1] = value
return return
def setOutlineLevel(self, value: str | None) -> None: def setOutlineLevel(self, value: str | None) -> None:
"""Set paragraph outline level."""
if value in self.VALID_LEVEL: if value in self.VALID_LEVEL:
self._mAttr["default-outline-level"][1] = value self._mAttr["default-outline-level"][1] = value
else: else:
@@ -1128,6 +1133,7 @@ class ODTParagraphStyle:
return return
def setClass(self, value: str | None) -> None: def setClass(self, value: str | None) -> None:
"""Set paragraph class."""
if value in self.VALID_CLASS: if value in self.VALID_CLASS:
self._mAttr["class"][1] = value self._mAttr["class"][1] = value
else: else:
@@ -1139,30 +1145,37 @@ class ODTParagraphStyle:
## ##
def setMarginTop(self, value: str | None) -> None: def setMarginTop(self, value: str | None) -> None:
"""Set paragraph top margin."""
self._pAttr["margin-top"][1] = value self._pAttr["margin-top"][1] = value
return return
def setMarginBottom(self, value: str | None) -> None: def setMarginBottom(self, value: str | None) -> None:
"""Set paragraph bottom margin."""
self._pAttr["margin-bottom"][1] = value self._pAttr["margin-bottom"][1] = value
return return
def setMarginLeft(self, value: str | None) -> None: def setMarginLeft(self, value: str | None) -> None:
"""Set paragraph left margin."""
self._pAttr["margin-left"][1] = value self._pAttr["margin-left"][1] = value
return return
def setMarginRight(self, value: str | None) -> None: def setMarginRight(self, value: str | None) -> None:
"""Set paragraph right margin."""
self._pAttr["margin-right"][1] = value self._pAttr["margin-right"][1] = value
return return
def setTextIndent(self, value: str | None) -> None: def setTextIndent(self, value: str | None) -> None:
"""Set text indentation."""
self._pAttr["text-indent"][1] = value self._pAttr["text-indent"][1] = value
return return
def setLineHeight(self, value: str | None) -> None: def setLineHeight(self, value: str | None) -> None:
"""Set line height."""
self._pAttr["line-height"][1] = value self._pAttr["line-height"][1] = value
return return
def setTextAlign(self, value: str | None) -> None: def setTextAlign(self, value: str | None) -> None:
"""Set paragraph text alignment."""
if value in self.VALID_ALIGN: if value in self.VALID_ALIGN:
self._pAttr["text-align"][1] = value self._pAttr["text-align"][1] = value
else: else:
@@ -1170,6 +1183,7 @@ class ODTParagraphStyle:
return return
def setBreakBefore(self, value: str | None) -> None: def setBreakBefore(self, value: str | None) -> None:
"""Set page break before policy."""
if value in self.VALID_BREAK: if value in self.VALID_BREAK:
self._pAttr["break-before"][1] = value self._pAttr["break-before"][1] = value
else: else:
@@ -1177,6 +1191,7 @@ class ODTParagraphStyle:
return return
def setBreakAfter(self, value: str | None) -> None: def setBreakAfter(self, value: str | None) -> None:
"""Set page break after policy."""
if value in self.VALID_BREAK: if value in self.VALID_BREAK:
self._pAttr["break-after"][1] = value self._pAttr["break-after"][1] = value
else: else:
@@ -1188,29 +1203,35 @@ class ODTParagraphStyle:
## ##
def setFontName(self, value: str | None) -> None: def setFontName(self, value: str | None) -> None:
"""Set font name."""
self._tAttr["font-name"][1] = value self._tAttr["font-name"][1] = value
return return
def setFontFamily(self, value: str | None) -> None: def setFontFamily(self, value: str | None) -> None:
"""Set font family."""
self._tAttr["font-family"][1] = value self._tAttr["font-family"][1] = value
return return
def setFontSize(self, value: str | None) -> None: def setFontSize(self, value: str | None) -> None:
"""Set font size."""
self._tAttr["font-size"][1] = value self._tAttr["font-size"][1] = value
return return
def setFontWeight(self, value: str | None) -> None: def setFontWeight(self, value: str | None) -> None:
"""Set font weight."""
if value in self.VALID_WEIGHT: if value in self.VALID_WEIGHT:
self._tAttr["font-weight"][1] = value self._tAttr["font-weight"][1] = value
else: else:
self._tAttr["font-weight"][1] = None self._tAttr["font-weight"][1] = None
return return
def setColor(self, value: str | None) -> None: def setColour(self, value: str | None) -> None:
"""Set text colour."""
self._tAttr["color"][1] = value self._tAttr["color"][1] = value
return return
def setOpacity(self, value: str | None) -> None: def setOpacity(self, value: str | None) -> None:
"""Set text opacity."""
self._tAttr["opacity"][1] = value self._tAttr["opacity"][1] = value
return return
+13 -11
View File
@@ -118,7 +118,7 @@ def testCoreToOdt_TextFormatting(mockGUI):
# Paragraph Style # Paragraph Style
# =============== # ===============
oStyle = ODTParagraphStyle() oStyle = ODTParagraphStyle("test")
assert odt._paraStyle("stuff", oStyle) == "Standard" assert odt._paraStyle("stuff", oStyle) == "Standard"
assert odt._paraStyle("Text_20_body", oStyle) == "Text_20_body" assert odt._paraStyle("Text_20_body", oStyle) == "Text_20_body"
@@ -142,7 +142,7 @@ def testCoreToOdt_TextFormatting(mockGUI):
# Paragraph Formatting # Paragraph Formatting
# ==================== # ====================
oStyle = ODTParagraphStyle() oStyle = ODTParagraphStyle("test")
# No Text # No Text
odt.initDocument() odt.initDocument()
@@ -714,6 +714,8 @@ def testCoreToOdt_SaveFlat(mockGUI, fncPath, tstPaths):
assert odt._colourHead is True assert odt._colourHead is True
odt.setHeaderFormat(nwHeadFmt.ODT_AUTO, 1) odt.setHeaderFormat(nwHeadFmt.ODT_AUTO, 1)
assert odt._headerFormat == nwHeadFmt.ODT_AUTO assert odt._headerFormat == nwHeadFmt.ODT_AUTO
odt.setFirstLineIndent(True)
assert odt._firstIndent is True
odt.setPageLayout(148, 210, 20, 18, 17, 15) odt.setPageLayout(148, 210, 20, 18, 17, 15)
assert odt._mDocWidth == "14.800cm" assert odt._mDocWidth == "14.800cm"
@@ -1024,7 +1026,7 @@ def testCoreToOdt_ODTParagraphStyle():
assert parStyle._tAttr["color"] == ["fo", None] assert parStyle._tAttr["color"] == ["fo", None]
assert parStyle._tAttr["opacity"] == ["loext", None] assert parStyle._tAttr["opacity"] == ["loext", None]
parStyle.setColor("#000000") parStyle.setColour("#000000")
parStyle.setOpacity("1.00") parStyle.setOpacity("1.00")
assert parStyle._tAttr["color"] == ["fo", "#000000"] assert parStyle._tAttr["color"] == ["fo", "#000000"]
@@ -1050,8 +1052,8 @@ def testCoreToOdt_ODTParagraphStyle():
# Changes # Changes
# ======= # =======
aStyle = ODTParagraphStyle() aStyle = ODTParagraphStyle("test")
oStyle = ODTParagraphStyle() oStyle = ODTParagraphStyle("test")
assert aStyle.checkNew(oStyle) is False assert aStyle.checkNew(oStyle) is False
assert aStyle.getID() == oStyle.getID() assert aStyle.getID() == oStyle.getID()
@@ -1060,17 +1062,17 @@ def testCoreToOdt_ODTParagraphStyle():
assert aStyle.checkNew(oStyle) is True assert aStyle.checkNew(oStyle) is True
assert aStyle.getID() != oStyle.getID() assert aStyle.getID() != oStyle.getID()
aStyle = ODTParagraphStyle() aStyle = ODTParagraphStyle("test")
oStyle = ODTParagraphStyle() oStyle = ODTParagraphStyle("test")
aStyle.setMarginTop("0.000cm") aStyle.setMarginTop("0.000cm")
oStyle.setMarginTop("1.000cm") oStyle.setMarginTop("1.000cm")
assert aStyle.checkNew(oStyle) is True assert aStyle.checkNew(oStyle) is True
assert aStyle.getID() != oStyle.getID() assert aStyle.getID() != oStyle.getID()
aStyle = ODTParagraphStyle() aStyle = ODTParagraphStyle("test")
oStyle = ODTParagraphStyle() oStyle = ODTParagraphStyle("test")
aStyle.setColor("#000000") aStyle.setColour("#000000")
oStyle.setColor("#111111") oStyle.setColour("#111111")
assert aStyle.checkNew(oStyle) is True assert aStyle.checkNew(oStyle) is True
assert aStyle.getID() != oStyle.getID() assert aStyle.getID() != oStyle.getID()