Files
novelWriter/tests/test_tools/test_tools_manussettings.py
T
Veronica Berglyd Olsen 91222f631f Update manuscript tests
2024-05-25 23:02:34 +02:00

701 lines
26 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
novelWriter Manuscript Build Settings Dialog Tester
=====================================================
This file is a part of novelWriter
Copyright 20182024, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
from __future__ import annotations
import pytest
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QFontDialog
from novelwriter import SHARED
from novelwriter.common import describeFont
from novelwriter.constants import nwHeadFmt
from novelwriter.core.buildsettings import BuildSettings, FilterMode
from novelwriter.tools.manussettings import (
GuiBuildSettings, _ContentTab, _FilterTab, _FormatTab, _HeadingsTab,
_OutputTab
)
from novelwriter.types import QtDialogApply, QtDialogClose, QtDialogSave
from tests.tools import C, buildTestProject
@pytest.mark.gui
def testToolBuildSettings_Init(qtbot, nwGUI, projPath, mockRnd):
"""Test the initialisation of the GuiBuildSettings dialog."""
buildTestProject(nwGUI, projPath)
nwGUI.openProject(projPath)
build = BuildSettings()
# Create the dialog and populate it
bSettings = GuiBuildSettings(nwGUI, build)
bSettings.show()
bSettings.loadContent()
# Flip through pages
bSettings.sidebar._group.button(bSettings.OPT_OUTPUT).click()
assert isinstance(bSettings.toolStack.currentWidget(), _OutputTab)
bSettings.sidebar._group.button(bSettings.OPT_FORMAT).click()
assert isinstance(bSettings.toolStack.currentWidget(), _FormatTab)
bSettings.sidebar._group.button(bSettings.OPT_CONTENT).click()
assert isinstance(bSettings.toolStack.currentWidget(), _ContentTab)
bSettings.sidebar._group.button(bSettings.OPT_HEADINGS).click()
assert isinstance(bSettings.toolStack.currentWidget(), _HeadingsTab)
bSettings.sidebar._group.button(bSettings.OPT_FILTERS).click()
assert isinstance(bSettings.toolStack.currentWidget(), _FilterTab)
# Check dialog buttons
triggered = False
@pyqtSlot(BuildSettings)
def _testNewSettingsReady(new: BuildSettings):
nonlocal build, triggered
assert new is build
triggered = True
# Capture Apply button
with qtbot.waitSignal(bSettings.newSettingsReady, timeout=5000):
bSettings.newSettingsReady.connect(_testNewSettingsReady)
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QtDialogApply))
assert triggered
# Capture Save button
triggered = False
with qtbot.waitSignal(bSettings.newSettingsReady, timeout=5000):
bSettings.newSettingsReady.connect(_testNewSettingsReady)
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QtDialogSave))
assert triggered
# Close manually
# This pops the ask to save dialog, which is automatically handled
triggered = False
build._changed = True
bSettings.show()
with qtbot.waitSignal(bSettings.newSettingsReady, timeout=5000):
bSettings.newSettingsReady.connect(_testNewSettingsReady)
bSettings.close()
assert triggered
# Finish
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QtDialogClose))
# qtbot.stop()
@pytest.mark.gui
def testToolBuildSettings_Filter(qtbot, nwGUI, projPath, mockRnd):
"""Test the Filter Tab of the GuiBuildSettings dialog."""
buildTestProject(nwGUI, projPath)
nwGUI.openProject(projPath)
build = BuildSettings()
switchMap = {
"incNovel": 1,
"incNotes": 2,
"incInactive": 3,
"novelRoot": 6,
"plotRoot": 7,
"charRoot": 8,
"worldRoot": 9,
}
hPlotDoc = SHARED.project.newFile("Main Plot", C.hPlotRoot)
hCharDoc = SHARED.project.newFile("Jane Doe", C.hCharRoot)
nwGUI.projView.projTree.revealNewTreeItem(hPlotDoc)
nwGUI.projView.projTree.revealNewTreeItem(hCharDoc)
SHARED.project.tree[hPlotDoc].setActive(False) # type: ignore
# Create the dialog and populate it
bSettings = GuiBuildSettings(nwGUI, build)
bSettings.show()
bSettings.loadContent()
filterTab = bSettings.optTabSelect
bSettings.sidebar._group.button(bSettings.OPT_FILTERS).click()
assert bSettings.toolStack.currentWidget() is filterTab
# Check content
assert filterTab.optTree.topLevelItemCount() == 4 # The 4 root folders
assert filterTab.filterOpt._index == 10 # 2 headers, 1 sep, 3 opt and 4 roots
# Un-toggle note folders
filterTab.filterOpt._widgets[switchMap["worldRoot"]].setChecked(False) # World Root
assert filterTab.optTree.topLevelItemCount() == 3
assert C.hWorldRoot in build._skipRoot
filterTab.filterOpt._widgets[switchMap["charRoot"]].setChecked(False) # Char Root
assert filterTab.optTree.topLevelItemCount() == 2
assert C.hCharRoot in build._skipRoot
filterTab.filterOpt._widgets[switchMap["plotRoot"]].setChecked(False) # Plot Root
assert filterTab.optTree.topLevelItemCount() == 1
assert C.hPlotRoot in build._skipRoot
# Reset Plot and Char
filterTab.filterOpt._widgets[switchMap["plotRoot"]].setChecked(True)
filterTab.filterOpt._widgets[switchMap["charRoot"]].setChecked(True)
assert filterTab.optTree.topLevelItemCount() == 3
# Switch off novel docs
filterTab.filterOpt._widgets[switchMap["incNovel"]].setChecked(False)
assert build.buildItemFilter(SHARED.project) == {
C.hNovelRoot: (False, FilterMode.SKIPPED),
C.hTitlePage: (False, FilterMode.FILTERED),
C.hChapterDir: (False, FilterMode.SKIPPED),
C.hChapterDoc: (False, FilterMode.FILTERED),
C.hSceneDoc: (False, FilterMode.FILTERED),
C.hPlotRoot: (False, FilterMode.SKIPPED),
hPlotDoc: (False, FilterMode.FILTERED),
C.hCharRoot: (False, FilterMode.SKIPPED),
hCharDoc: (False, FilterMode.FILTERED),
C.hWorldRoot: (False, FilterMode.SKIPPED),
}
# Switch on note docs
filterTab.filterOpt._widgets[switchMap["incNotes"]].setChecked(True)
assert build.buildItemFilter(SHARED.project) == {
C.hNovelRoot: (False, FilterMode.SKIPPED),
C.hTitlePage: (False, FilterMode.FILTERED),
C.hChapterDir: (False, FilterMode.SKIPPED),
C.hChapterDoc: (False, FilterMode.FILTERED),
C.hSceneDoc: (False, FilterMode.FILTERED),
C.hPlotRoot: (False, FilterMode.SKIPPED),
hPlotDoc: (False, FilterMode.FILTERED), # Set to inactive
C.hCharRoot: (False, FilterMode.SKIPPED),
hCharDoc: (True, FilterMode.FILTERED), # Now enabled
C.hWorldRoot: (False, FilterMode.SKIPPED),
}
# Switch on inactive docs
filterTab.filterOpt._widgets[switchMap["incInactive"]].setChecked(True)
assert build.buildItemFilter(SHARED.project) == {
C.hNovelRoot: (False, FilterMode.SKIPPED),
C.hTitlePage: (False, FilterMode.FILTERED),
C.hChapterDir: (False, FilterMode.SKIPPED),
C.hChapterDoc: (False, FilterMode.FILTERED),
C.hSceneDoc: (False, FilterMode.FILTERED),
C.hPlotRoot: (False, FilterMode.SKIPPED),
hPlotDoc: (True, FilterMode.FILTERED), # Now enabled
C.hCharRoot: (False, FilterMode.SKIPPED),
hCharDoc: (True, FilterMode.FILTERED),
C.hWorldRoot: (False, FilterMode.SKIPPED),
}
# Set chapter and scene docs to included
filterTab._treeMap[C.hChapterDoc].setSelected(True)
filterTab._treeMap[C.hSceneDoc].setSelected(True)
filterTab.includedButton.click()
assert build.buildItemFilter(SHARED.project) == {
C.hNovelRoot: (False, FilterMode.SKIPPED),
C.hTitlePage: (False, FilterMode.FILTERED),
C.hChapterDir: (False, FilterMode.SKIPPED),
C.hChapterDoc: (True, FilterMode.INCLUDED), # Now included
C.hSceneDoc: (True, FilterMode.INCLUDED), # Now included
C.hPlotRoot: (False, FilterMode.SKIPPED),
hPlotDoc: (True, FilterMode.FILTERED),
C.hCharRoot: (False, FilterMode.SKIPPED),
hCharDoc: (True, FilterMode.FILTERED),
C.hWorldRoot: (False, FilterMode.SKIPPED),
}
# Set char and plot docs to excluded
filterTab.optTree.clearSelection()
filterTab._treeMap[hPlotDoc].setSelected(True) # type: ignore
filterTab._treeMap[hCharDoc].setSelected(True) # type: ignore
filterTab.excludedButton.click()
assert build.buildItemFilter(SHARED.project) == {
C.hNovelRoot: (False, FilterMode.SKIPPED),
C.hTitlePage: (False, FilterMode.FILTERED),
C.hChapterDir: (False, FilterMode.SKIPPED),
C.hChapterDoc: (True, FilterMode.INCLUDED),
C.hSceneDoc: (True, FilterMode.INCLUDED),
C.hPlotRoot: (False, FilterMode.SKIPPED),
hPlotDoc: (False, FilterMode.EXCLUDED), # Now excluded
C.hCharRoot: (False, FilterMode.SKIPPED),
hCharDoc: (False, FilterMode.EXCLUDED), # Now excluded
C.hWorldRoot: (False, FilterMode.SKIPPED),
}
# Switch on novel docs
filterTab.filterOpt._widgets[switchMap["incNovel"]].setChecked(True)
assert build.buildItemFilter(SHARED.project) == {
C.hNovelRoot: (False, FilterMode.SKIPPED),
C.hTitlePage: (True, FilterMode.FILTERED), # Now enabled
C.hChapterDir: (False, FilterMode.SKIPPED),
C.hChapterDoc: (True, FilterMode.INCLUDED),
C.hSceneDoc: (True, FilterMode.INCLUDED),
C.hPlotRoot: (False, FilterMode.SKIPPED),
hPlotDoc: (False, FilterMode.EXCLUDED),
C.hCharRoot: (False, FilterMode.SKIPPED),
hCharDoc: (False, FilterMode.EXCLUDED),
C.hWorldRoot: (False, FilterMode.SKIPPED),
}
# Selecting only novel root should iterate through all children
filterTab.optTree.clearSelection()
filterTab._treeMap[C.hNovelRoot].setSelected(True)
filterTab.resetButton.click()
assert build.buildItemFilter(SHARED.project) == {
C.hNovelRoot: (False, FilterMode.SKIPPED),
C.hTitlePage: (True, FilterMode.FILTERED),
C.hChapterDir: (False, FilterMode.SKIPPED),
C.hChapterDoc: (True, FilterMode.FILTERED),
C.hSceneDoc: (True, FilterMode.FILTERED),
C.hPlotRoot: (False, FilterMode.SKIPPED),
hPlotDoc: (False, FilterMode.EXCLUDED),
C.hCharRoot: (False, FilterMode.SKIPPED),
hCharDoc: (False, FilterMode.EXCLUDED),
C.hWorldRoot: (False, FilterMode.SKIPPED),
}
# Set everything back to filtered
filterTab.optTree.clearSelection()
filterTab._treeMap[C.hNovelRoot].setSelected(True)
filterTab._treeMap[C.hSceneDoc].setSelected(True)
filterTab._treeMap[hPlotDoc].setSelected(True) # type: ignore
filterTab._treeMap[hCharDoc].setSelected(True) # type: ignore
filterTab.resetButton.click()
assert build.buildItemFilter(SHARED.project) == {
C.hNovelRoot: (False, FilterMode.SKIPPED),
C.hTitlePage: (True, FilterMode.FILTERED),
C.hChapterDir: (False, FilterMode.SKIPPED),
C.hChapterDoc: (True, FilterMode.FILTERED),
C.hSceneDoc: (True, FilterMode.FILTERED),
C.hPlotRoot: (False, FilterMode.SKIPPED),
hPlotDoc: (True, FilterMode.FILTERED),
C.hCharRoot: (False, FilterMode.SKIPPED),
hCharDoc: (True, FilterMode.FILTERED),
C.hWorldRoot: (False, FilterMode.SKIPPED),
}
# Check handling of invalid project items
assert list(filterTab._treeMap.keys()) == [
C.hNovelRoot, C.hTitlePage, C.hChapterDir, C.hChapterDoc, C.hSceneDoc,
C.hPlotRoot, hPlotDoc, C.hCharRoot, hCharDoc,
]
SHARED.project.tree[hCharDoc].setRoot(None) # type: ignore
SHARED.project.tree[hPlotDoc].setParent(None) # type: ignore
filterTab._populateTree()
assert list(filterTab._treeMap.keys()) == [
C.hNovelRoot, C.hTitlePage, C.hChapterDir, C.hChapterDoc, C.hSceneDoc,
C.hPlotRoot, C.hCharRoot
]
# Finish
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QtDialogClose))
# qtbot.stop()
@pytest.mark.gui
def testToolBuildSettings_Headings(qtbot, nwGUI):
"""Test the Headings Tab of the GuiBuildSettings dialog."""
build = BuildSettings()
ttTitle = f"Title: {nwHeadFmt.TITLE}"
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.fmtAltScene", shTitle)
build.setValue("headings.fmtSection", sxTitle)
build.setValue("headings.hideScene", False)
build.setValue("headings.hideSection", False)
# Create the dialog and populate it
bSettings = GuiBuildSettings(nwGUI, build)
bSettings.show()
bSettings.loadContent()
headTab = bSettings.optTabHeadings
bSettings.sidebar._group.button(bSettings.OPT_HEADINGS).click()
assert bSettings.toolStack.currentWidget() is headTab
# Check initial values
assert headTab.fmtTitle.text() == ttTitle
assert headTab.fmtChapter.text() == chTitle
assert headTab.fmtUnnumbered.text() == unTitle
assert headTab.fmtScene.text() == scTitle
assert headTab.fmtAScene.text() == shTitle
assert headTab.fmtSection.text() == sxTitle
assert headTab.swtScene.isChecked() is False
assert headTab.swtSection.isChecked() is False
# Edit in Turn
# ============
# Nothing to apply
assert headTab._editing == 0
assert headTab.editTextBox.isEnabled() is False
headTab.btnApply.click()
assert headTab.editTextBox.isEnabled() is False
# Title
headTab.btnTitle.click()
assert headTab._editing == headTab.EDIT_TITLE
assert headTab.editTextBox.isEnabled() is True
assert headTab.editTextBox.toPlainText() == ttTitle
headTab.btnApply.click()
assert headTab.editTextBox.isEnabled() is False
# Chapter
headTab.btnChapter.click()
assert headTab._editing == headTab.EDIT_CHAPTER
assert headTab.editTextBox.isEnabled() is True
assert headTab.editTextBox.toPlainText() == chTitle
headTab.btnApply.click()
assert headTab.editTextBox.isEnabled() is False
# Unnumbered
headTab.btnUnnumbered.click()
assert headTab._editing == headTab.EDIT_UNNUM
assert headTab.editTextBox.isEnabled() is True
assert headTab.editTextBox.toPlainText() == unTitle
headTab.btnApply.click()
assert headTab.editTextBox.isEnabled() is False
# Scene
headTab.btnScene.click()
assert headTab._editing == headTab.EDIT_SCENE
assert headTab.editTextBox.isEnabled() is True
assert headTab.editTextBox.toPlainText() == scTitle
headTab.btnApply.click()
assert headTab.editTextBox.isEnabled() is False
# Hard Scene
headTab.btnAScene.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
assert headTab.editTextBox.isEnabled() is True
assert headTab.editTextBox.toPlainText() == sxTitle
headTab.btnApply.click()
assert headTab.editTextBox.isEnabled() is False
# Edit a Heading
# ==============
# Create new format of all bits
headTab.btnChapter.click()
allFmt = (
f"{nwHeadFmt.TITLE}{nwHeadFmt.CH_NUM}{nwHeadFmt.CH_WORD}{nwHeadFmt.CH_ROMU}"
f"{nwHeadFmt.CH_ROML}{nwHeadFmt.SC_NUM}{nwHeadFmt.SC_ABS}"
)
headTab.editTextBox.clear()
assert headTab.editTextBox.toPlainText() == ""
headTab.aInsTitle.trigger()
headTab.aInsChNum.trigger()
headTab.aInsChWord.trigger()
headTab.aInsChRomU.trigger()
headTab.aInsChRomL.trigger()
headTab.aInsScNum.trigger()
headTab.aInsScAbs.trigger()
assert headTab.editTextBox.toPlainText() == allFmt
headTab.btnApply.click()
assert build.getStr("headings.fmtChapter") == allFmt
# Check complex format
headTab.btnChapter.click()
headTab.editTextBox.setPlainText(f"Chapter {nwHeadFmt.CH_NUM}\n{nwHeadFmt.TITLE}\n")
headTab.btnApply.click()
assert build.getStr("headings.fmtChapter") == (
f"Chapter {nwHeadFmt.CH_NUM}{nwHeadFmt.BR}{nwHeadFmt.TITLE}"
)
# Set all to plain title
headTab.btnTitle.click()
headTab.editTextBox.setPlainText(nwHeadFmt.TITLE)
headTab.btnApply.click()
assert build.getStr("headings.fmtTitle") == nwHeadFmt.TITLE
headTab.btnChapter.click()
headTab.editTextBox.setPlainText(nwHeadFmt.TITLE)
headTab.btnApply.click()
assert build.getStr("headings.fmtChapter") == nwHeadFmt.TITLE
headTab.btnUnnumbered.click()
headTab.editTextBox.setPlainText(nwHeadFmt.TITLE)
headTab.btnApply.click()
assert build.getStr("headings.fmtUnnumbered") == nwHeadFmt.TITLE
headTab.btnScene.click()
headTab.editTextBox.setPlainText(nwHeadFmt.TITLE)
headTab.btnApply.click()
assert build.getStr("headings.fmtScene") == nwHeadFmt.TITLE
headTab.btnAScene.click()
headTab.editTextBox.setPlainText(nwHeadFmt.TITLE)
headTab.btnApply.click()
assert build.getStr("headings.fmtAltScene") == nwHeadFmt.TITLE
headTab.btnSection.click()
headTab.editTextBox.setPlainText(nwHeadFmt.TITLE)
headTab.btnApply.click()
assert build.getStr("headings.fmtSection") == nwHeadFmt.TITLE
# Check hide switches
headTab.swtScene.setChecked(True)
headTab.swtSection.setChecked(True)
headTab.saveContent()
assert build.getBool("headings.hideScene") is True
assert build.getBool("headings.hideSection") is True
# Finish
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QtDialogClose))
# qtbot.stop()
@pytest.mark.gui
def testToolBuildSettings_Content(qtbot, nwGUI):
"""Test the Content Tab of the GuiBuildSettings dialog."""
build = BuildSettings()
build.setValue("text.includeBodyText", False)
build.setValue("text.includeSynopsis", False)
build.setValue("text.includeComments", False)
build.setValue("text.includeKeywords", False)
build.setValue("text.ignoredKeywords", "")
build.setValue("text.addNoteHeadings", False)
# Create the dialog and populate it
bSettings = GuiBuildSettings(nwGUI, build)
bSettings.show()
bSettings.loadContent()
contTab = bSettings.optTabContent
bSettings.sidebar._group.button(bSettings.OPT_CONTENT).click()
assert bSettings.toolStack.currentWidget() is contTab
# Check initial values
assert contTab.incBodyText.isChecked() is False
assert contTab.incSynopsis.isChecked() is False
assert contTab.incComments.isChecked() is False
assert contTab.incKeywords.isChecked() is False
assert contTab.ignoredKeywords.text() == ""
assert contTab.addNoteHead.isChecked() is False
# Toggle switches
contTab.incBodyText.setChecked(True)
contTab.incSynopsis.setChecked(True)
contTab.incComments.setChecked(True)
contTab.incKeywords.setChecked(True)
contTab.addNoteHead.setChecked(True)
# Test cleanup of ignored keywords
contTab.ignoredKeywords.setText("@stuff, @pizza, @object") # First two are invalid
contTab._updateIgnoredKeywords("@custom") # Adding a new should trigger cleanup
assert contTab.ignoredKeywords.text() in ("@custom, @object", "@object, @custom")
# Save values
contTab.saveContent()
assert build.getBool("text.includeBodyText") is True
assert build.getBool("text.includeSynopsis") is True
assert build.getBool("text.includeComments") is True
assert build.getBool("text.includeKeywords") is True
assert build.getStr("text.ignoredKeywords") in ("@custom, @object", "@object, @custom")
assert build.getBool("text.addNoteHeadings") is True
# Finish
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QtDialogClose))
# qtbot.stop()
@pytest.mark.gui
def testToolBuildSettings_Format(monkeypatch, qtbot, nwGUI):
"""Test the Format Tab of the GuiBuildSettings dialog."""
build = BuildSettings()
build.setValue("format.buildLang", "en_US")
build.setValue("format.textFont", "") # Will fall back to config value
build.setValue("format.lineHeight", 1.2)
build.setValue("format.justifyText", False)
build.setValue("format.stripUnicode", False)
build.setValue("format.replaceTabs", False)
build.setValue("format.pageUnit", "mm")
build.setValue("format.pageSize", "Custom")
build.setValue("format.pageWidth", 180.0)
build.setValue("format.pageHeight", 250.0)
build.setValue("format.topMargin", 25.0)
build.setValue("format.bottomMargin", 25.0)
build.setValue("format.leftMargin", 15.0)
build.setValue("format.rightMargin", 15.0)
# Create the dialog and populate it
bSettings = GuiBuildSettings(nwGUI, build)
bSettings.show()
bSettings.loadContent()
fmtTab = bSettings.optTabFormat
bSettings.sidebar._group.button(bSettings.OPT_FORMAT).click()
assert bSettings.toolStack.currentWidget() is fmtTab
# Check initial values
assert fmtTab.lineHeight.value() == 1.2
assert fmtTab.justifyText.isChecked() is False
assert fmtTab.stripUnicode.isChecked() is False
assert fmtTab.replaceTabs.isChecked() is False
assert fmtTab.firstIndent.isChecked() is False
assert fmtTab.indentWidth.value() == 1.4
assert fmtTab.indentFirstPar.isChecked() is False
assert fmtTab.pageUnit.currentData() == "mm"
assert fmtTab.pageSize.currentData() == "Custom"
assert fmtTab.pageWidth.value() == 180.0
assert fmtTab.pageHeight.value() == 250.0
assert fmtTab.topMargin.value() == 25.0
assert fmtTab.bottomMargin.value() == 25.0
assert fmtTab.leftMargin.value() == 15.0
assert fmtTab.rightMargin.value() == 15.0
# Change values
testFont = QFont("Arial", 11)
fmtTab._textFont = testFont
fmtTab.textFont.setText(describeFont(testFont))
fmtTab.lineHeight.setValue(1.15)
fmtTab.justifyText.setChecked(True)
fmtTab.stripUnicode.setChecked(True)
fmtTab.replaceTabs.setChecked(True)
fmtTab.firstIndent.setChecked(True)
fmtTab.indentWidth.setValue(2.0)
fmtTab.indentFirstPar.setChecked(True)
fmtTab.pageUnit.setCurrentIndex(fmtTab.pageUnit.findData("cm"))
fmtTab.pageSize.setCurrentIndex(fmtTab.pageSize.findData("A4"))
# Save values
fmtTab.saveContent()
assert build.getStr("format.textFont") == testFont.toString()
assert build.getFloat("format.lineHeight") == 1.15
assert build.getBool("format.justifyText") is True
assert build.getBool("format.stripUnicode") is True
assert build.getBool("format.replaceTabs") is True
assert build.getBool("format.firstLineIndent") is True
assert build.getFloat("format.firstIndentWidth") == 2.0
assert build.getBool("format.indentFirstPar") is True
assert fmtTab.pageUnit.currentData() == "cm"
assert fmtTab.pageSize.currentData() == "A4"
assert fmtTab.pageWidth.value() == 21.0
assert fmtTab.pageHeight.value() == 29.7
assert fmtTab.topMargin.value() == 2.5
assert fmtTab.bottomMargin.value() == 2.5
assert fmtTab.leftMargin.value() == 1.5
assert fmtTab.rightMargin.value() == 1.5
# Check that the font dialog doesn't fail
with monkeypatch.context() as mp:
font = QFont()
font.setFamily("Times")
font.setPointSize(10)
mp.setattr(QFontDialog, "getFont", lambda *a, **k: (font, True))
fmtTab.btnTextFont.click()
assert fmtTab._textFont == font
# Finish
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QtDialogClose))
# qtbot.stop()
@pytest.mark.gui
def testToolBuildSettings_Output(qtbot, nwGUI):
"""Test the Output Tab of the GuiBuildSettings dialog."""
build = BuildSettings()
build.setValue("odt.addColours", False)
build.setValue("html.addStyles", False)
# Create the dialog and populate it
bSettings = GuiBuildSettings(nwGUI, build)
bSettings.show()
bSettings.loadContent()
outTab = bSettings.optTabOutput
bSettings.sidebar._group.button(bSettings.OPT_OUTPUT).click()
assert bSettings.toolStack.currentWidget() is outTab
# Check initial values
assert outTab.odtAddColours.isChecked() is False
assert outTab.odtPageHeader.text() == nwHeadFmt.ODT_AUTO
assert outTab.odtPageCountOffset.value() == 0
assert outTab.htmlAddStyles.isChecked() is False
assert outTab.htmlPreserveTabs.isChecked() is False
# Toggle all
outTab.odtAddColours.setChecked(True)
outTab.htmlAddStyles.setChecked(True)
outTab.htmlPreserveTabs.setChecked(True)
# Change Values
outTab.odtPageCountOffset.setValue(1)
outTab.odtPageHeader.setText("Stuff")
# Save values
outTab.saveContent()
assert build.getBool("odt.addColours") is True
assert build.getStr("odt.pageHeader") == "Stuff"
assert build.getInt("odt.pageCountOffset") == 1
assert build.getBool("html.addStyles") is True
assert build.getBool("html.preserveTabs") is True
# Reset header format
outTab.btnPageHeader.click()
assert outTab.odtPageHeader.text() == nwHeadFmt.ODT_AUTO
# Finish
bSettings._dialogButtonClicked(bSettings.buttonBox.button(QtDialogClose))
# qtbot.stop()