Remove scaling and add slots to main config class
This commit is contained in:
+51
-73
@@ -52,6 +52,31 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
class Config:
|
||||
|
||||
__slots__ = (
|
||||
"_confPath", "_dataPath", "_homePath", "_backPath", "_appPath", "_appRoot", "_hasError",
|
||||
"_errData", "_nwLangPath", "_qtLangPath", "_qLocale", "_dLocale", "_dShortDate",
|
||||
"_dShortDateTime", "_qtTrans", "_recentProjects", "_recentPaths", "_backupPath",
|
||||
|
||||
"appName", "appHandle", "pdfDocs", "guiLocale", "guiTheme", "guiSyntax", "guiFont",
|
||||
"hideVScroll", "hideHScroll", "lastNotes", "nativeFont", "iconTheme", "iconColTree",
|
||||
"iconColDocs", "mainWinSize", "welcomeWinSize", "prefsWinSize", "mainPanePos",
|
||||
"viewPanePos", "outlinePanePos", "autoSaveProj", "autoSaveDoc", "emphLabels",
|
||||
"backupOnClose", "askBeforeBackup", "textFont", "textWidth", "textMargin", "tabWidth",
|
||||
"focusWidth", "hideFocusFooter", "showFullPath", "autoSelect", "doJustify",
|
||||
"showTabsNSpaces", "showLineEndings", "showMultiSpaces", "doReplace", "doReplaceSQuote",
|
||||
"doReplaceDQuote", "doReplaceDash", "doReplaceDots", "autoScroll", "autoScrollPos",
|
||||
"scrollPastEnd", "dialogStyle", "allowOpenDial", "dialogLine", "narratorBreak",
|
||||
"narratorDialog", "altDialogOpen", "altDialogClose", "highlightEmph", "stopWhenIdle",
|
||||
"userIdleTime", "incNotesWCount", "fmtApostrophe", "fmtSQuoteOpen", "fmtSQuoteClose",
|
||||
"fmtDQuoteOpen", "fmtDQuoteClose", "fmtPadBefore", "fmtPadAfter", "fmtPadThin",
|
||||
"spellLanguage", "showViewerPanel", "showEditToolBar", "showSessionTime", "viewComments",
|
||||
"viewSynopsis", "searchCase", "searchWord", "searchRegEx", "searchLoop", "searchNextFile",
|
||||
"searchMatchCap", "searchProjCase", "searchProjWord", "searchProjRegEx", "verQtString",
|
||||
"verQtValue", "verPyQtString", "verPyQtValue", "verPyString", "osType", "osLinux",
|
||||
"osWindows", "osDarwin", "osUnknown", "hostName", "kernelVer", "isDebug", "memInfo",
|
||||
"hasEnchant",
|
||||
)
|
||||
|
||||
LANG_NW = 1
|
||||
LANG_PROJ = 2
|
||||
|
||||
@@ -126,12 +151,12 @@ class Config:
|
||||
self.iconColDocs = False # Keep theme colours on documents
|
||||
|
||||
# Size Settings
|
||||
self._mainWinSize = [1200, 650] # Last size of the main GUI window
|
||||
self._welcomeSize = [800, 550] # Last size of the welcome window
|
||||
self._prefsWinSize = [700, 615] # Last size of the Preferences dialog
|
||||
self._mainPanePos = [300, 800] # Last position of the main window splitter
|
||||
self._viewPanePos = [500, 150] # Last position of the document viewer splitter
|
||||
self._outlnPanePos = [500, 150] # Last position of the outline panel splitter
|
||||
self.mainWinSize = [1200, 650] # Last size of the main GUI window
|
||||
self.welcomeWinSize = [800, 550] # Last size of the welcome window
|
||||
self.prefsWinSize = [700, 615] # Last size of the Preferences dialog
|
||||
self.mainPanePos = [300, 800] # Last position of the main window splitter
|
||||
self.viewPanePos = [500, 150] # Last position of the document viewer splitter
|
||||
self.outlinePanePos = [500, 150] # Last position of the outline panel splitter
|
||||
|
||||
# Project Settings
|
||||
self.autoSaveProj = 60 # Interval for auto-saving project, in seconds
|
||||
@@ -269,30 +294,6 @@ class Config:
|
||||
def recentProjects(self) -> RecentProjects:
|
||||
return self._recentProjects
|
||||
|
||||
@property
|
||||
def mainWinSize(self) -> list[int]:
|
||||
return self._mainWinSize
|
||||
|
||||
@property
|
||||
def welcomeWinSize(self) -> list[int]:
|
||||
return self._welcomeSize
|
||||
|
||||
@property
|
||||
def preferencesWinSize(self) -> list[int]:
|
||||
return self._prefsWinSize
|
||||
|
||||
@property
|
||||
def mainPanePos(self) -> list[int]:
|
||||
return self._mainPanePos
|
||||
|
||||
@property
|
||||
def viewPanePos(self) -> list[int]:
|
||||
return self._viewPanePos
|
||||
|
||||
@property
|
||||
def outlinePanePos(self) -> list[int]:
|
||||
return self._outlnPanePos
|
||||
|
||||
##
|
||||
# Getters
|
||||
##
|
||||
@@ -300,17 +301,9 @@ class Config:
|
||||
def getTextWidth(self, focusMode: bool = False) -> int:
|
||||
"""Get the text with for the correct editor mode."""
|
||||
if focusMode:
|
||||
return self.pxInt(max(self.focusWidth, 200))
|
||||
return max(self.focusWidth, 200)
|
||||
else:
|
||||
return self.pxInt(max(self.textWidth, 200))
|
||||
|
||||
def getTextMargin(self) -> int:
|
||||
"""Get the scaled text margin."""
|
||||
return self.pxInt(max(self.textMargin, 0))
|
||||
|
||||
def getTabWidth(self) -> int:
|
||||
"""Get the scaled tab width."""
|
||||
return self.pxInt(max(self.tabWidth, 0))
|
||||
return max(self.textWidth, 200)
|
||||
|
||||
##
|
||||
# Setters
|
||||
@@ -322,35 +315,20 @@ class Config:
|
||||
adjust it a bit, and we don't want the main window to shrink or
|
||||
grow each time the app is opened.
|
||||
"""
|
||||
if abs(self._mainWinSize[0] - width) > 5:
|
||||
self._mainWinSize[0] = width
|
||||
if abs(self._mainWinSize[1] - height) > 5:
|
||||
self._mainWinSize[1] = height
|
||||
if abs(self.mainWinSize[0] - width) > 5:
|
||||
self.mainWinSize[0] = width
|
||||
if abs(self.mainWinSize[1] - height) > 5:
|
||||
self.mainWinSize[1] = height
|
||||
return
|
||||
|
||||
def setWelcomeWinSize(self, width: int, height: int) -> None:
|
||||
"""Set the size of the Preferences dialog window."""
|
||||
self._welcomeSize = [width, height]
|
||||
self.welcomeWinSize = [width, height]
|
||||
return
|
||||
|
||||
def setPreferencesWinSize(self, width: int, height: int) -> None:
|
||||
"""Set the size of the Preferences dialog window."""
|
||||
self._prefsWinSize = [width, height]
|
||||
return
|
||||
|
||||
def setMainPanePos(self, pos: list[int]) -> None:
|
||||
"""Set the position of the main GUI splitter."""
|
||||
self._mainPanePos = pos
|
||||
return
|
||||
|
||||
def setViewPanePos(self, pos: list[int]) -> None:
|
||||
"""Set the position of the viewer meta data splitter."""
|
||||
self._viewPanePos = pos
|
||||
return
|
||||
|
||||
def setOutlinePanePos(self, pos: list[int]) -> None:
|
||||
"""Set the position of the outline details splitter."""
|
||||
self._outlnPanePos = pos
|
||||
self.prefsWinSize = [width, height]
|
||||
return
|
||||
|
||||
def setLastPath(self, key: str, path: str | Path) -> None:
|
||||
@@ -614,12 +592,12 @@ class Config:
|
||||
|
||||
# Sizes
|
||||
sec = "Sizes"
|
||||
self._mainWinSize = conf.rdIntList(sec, "mainwindow", self._mainWinSize)
|
||||
self._welcomeSize = conf.rdIntList(sec, "welcome", self._welcomeSize)
|
||||
self._prefsWinSize = conf.rdIntList(sec, "preferences", self._prefsWinSize)
|
||||
self._mainPanePos = conf.rdIntList(sec, "mainpane", self._mainPanePos)
|
||||
self._viewPanePos = conf.rdIntList(sec, "viewpane", self._viewPanePos)
|
||||
self._outlnPanePos = conf.rdIntList(sec, "outlinepane", self._outlnPanePos)
|
||||
self.mainWinSize = conf.rdIntList(sec, "mainwindow", self.mainWinSize)
|
||||
self.welcomeWinSize = conf.rdIntList(sec, "welcome", self.welcomeWinSize)
|
||||
self.prefsWinSize = conf.rdIntList(sec, "preferences", self.prefsWinSize)
|
||||
self.mainPanePos = conf.rdIntList(sec, "mainpane", self.mainPanePos)
|
||||
self.viewPanePos = conf.rdIntList(sec, "viewpane", self.viewPanePos)
|
||||
self.outlinePanePos = conf.rdIntList(sec, "outlinepane", self.outlinePanePos)
|
||||
|
||||
# Project
|
||||
sec = "Project"
|
||||
@@ -728,12 +706,12 @@ class Config:
|
||||
}
|
||||
|
||||
conf["Sizes"] = {
|
||||
"mainwindow": self._packList(self._mainWinSize),
|
||||
"welcome": self._packList(self._welcomeSize),
|
||||
"preferences": self._packList(self._prefsWinSize),
|
||||
"mainpane": self._packList(self._mainPanePos),
|
||||
"viewpane": self._packList(self._viewPanePos),
|
||||
"outlinepane": self._packList(self._outlnPanePos),
|
||||
"mainwindow": self._packList(self.mainWinSize),
|
||||
"welcome": self._packList(self.welcomeWinSize),
|
||||
"preferences": self._packList(self.prefsWinSize),
|
||||
"mainpane": self._packList(self.mainPanePos),
|
||||
"viewpane": self._packList(self.viewPanePos),
|
||||
"outlinepane": self._packList(self.outlinePanePos),
|
||||
}
|
||||
|
||||
conf["Project"] = {
|
||||
|
||||
@@ -59,7 +59,7 @@ class GuiPreferences(NDialog):
|
||||
self.setObjectName("GuiPreferences")
|
||||
self.setWindowTitle(self.tr("Preferences"))
|
||||
self.setMinimumSize(CONFIG.pxInt(600), CONFIG.pxInt(500))
|
||||
self.resize(*CONFIG.preferencesWinSize)
|
||||
self.resize(*CONFIG.prefsWinSize)
|
||||
|
||||
# Title
|
||||
self.titleLabel = NColourLabel(
|
||||
|
||||
@@ -331,7 +331,7 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
# Due to cursor visibility, a part of the margin must be
|
||||
# allocated to the document itself. See issue #1112.
|
||||
self._qDocument.setDocumentMargin(4)
|
||||
self._vpMargin = max(CONFIG.getTextMargin() - 4, 0)
|
||||
self._vpMargin = max(CONFIG.textMargin - 4, 0)
|
||||
self.setViewportMargins(self._vpMargin, self._vpMargin, self._vpMargin, self._vpMargin)
|
||||
|
||||
# Also set the document text options for the document text flow
|
||||
@@ -359,7 +359,7 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
self.setHorizontalScrollBarPolicy(QtScrollAsNeeded)
|
||||
|
||||
# Refresh the tab stops
|
||||
self.setTabStopDistance(CONFIG.getTabWidth())
|
||||
self.setTabStopDistance(CONFIG.tabWidth)
|
||||
|
||||
# If we have a document open, we should refresh it in case the
|
||||
# font changed, otherwise we just clear the editor entirely,
|
||||
|
||||
@@ -200,7 +200,7 @@ class GuiDocViewer(QTextBrowser):
|
||||
self.setHorizontalScrollBarPolicy(QtScrollAsNeeded)
|
||||
|
||||
# Refresh the tab stops
|
||||
self.setTabStopDistance(CONFIG.getTabWidth())
|
||||
self.setTabStopDistance(CONFIG.tabWidth)
|
||||
|
||||
# If we have a document open, we should reload it in case the font changed
|
||||
self.reloadText()
|
||||
@@ -250,7 +250,7 @@ class GuiDocViewer(QTextBrowser):
|
||||
|
||||
self.setDocumentTitle(tHandle)
|
||||
self.setDocument(qDoc.document)
|
||||
self.setTabStopDistance(CONFIG.getTabWidth())
|
||||
self.setTabStopDistance(CONFIG.tabWidth)
|
||||
|
||||
if self._docHandle == tHandle:
|
||||
# This is a refresh, so we set the scrollbar back to where it was
|
||||
@@ -308,7 +308,7 @@ class GuiDocViewer(QTextBrowser):
|
||||
"""Automatically adjust the margins so the text is centred."""
|
||||
wW = self.width()
|
||||
wH = self.height()
|
||||
cM = CONFIG.getTextMargin()
|
||||
cM = CONFIG.textMargin
|
||||
|
||||
vBar = self.verticalScrollBar()
|
||||
sW = vBar.width() if vBar.isVisible() else 0
|
||||
|
||||
@@ -860,10 +860,10 @@ class GuiMain(QMainWindow):
|
||||
logger.info("Exiting novelWriter")
|
||||
|
||||
if not SHARED.focusMode:
|
||||
CONFIG.setMainPanePos(self.splitMain.sizes())
|
||||
CONFIG.setOutlinePanePos(self.outlineView.splitSizes())
|
||||
CONFIG.mainPanePos = self.splitMain.sizes()
|
||||
CONFIG.outlinePanePos = self.outlineView.splitSizes()
|
||||
if self.docViewerPanel.isVisible():
|
||||
CONFIG.setViewPanePos(self.splitView.sizes())
|
||||
CONFIG.viewPanePos = self.splitView.sizes()
|
||||
|
||||
CONFIG.showViewerPanel = self.docViewerPanel.isVisible()
|
||||
wFull = Qt.WindowState.WindowFullScreen
|
||||
|
||||
@@ -750,11 +750,11 @@ class _PreviewWidget(QTextBrowser):
|
||||
self.setPalette(dPalette)
|
||||
|
||||
self.setMinimumWidth(40*SHARED.theme.textNWidth)
|
||||
self.setTabStopDistance(CONFIG.getTabWidth())
|
||||
self.setTabStopDistance(CONFIG.tabWidth)
|
||||
self.setOpenExternalLinks(False)
|
||||
self.setOpenLinks(False)
|
||||
|
||||
self.document().setDocumentMargin(CONFIG.getTextMargin())
|
||||
self.document().setDocumentMargin(CONFIG.textMargin)
|
||||
self.setPlaceholderText(self.tr(
|
||||
"Press the \"Preview\" button to generate ..."
|
||||
))
|
||||
@@ -852,9 +852,9 @@ class _PreviewWidget(QTextBrowser):
|
||||
self.buildProgress.setCentreText(self.tr("Processing ..."))
|
||||
QApplication.processEvents()
|
||||
|
||||
document.setDocumentMargin(CONFIG.getTextMargin())
|
||||
document.setDocumentMargin(CONFIG.textMargin)
|
||||
self.setDocument(document)
|
||||
self.setTabStopDistance(CONFIG.getTabWidth())
|
||||
self.setTabStopDistance(CONFIG.tabWidth)
|
||||
|
||||
self._docTime = int(time())
|
||||
self._updateBuildAge()
|
||||
|
||||
@@ -254,52 +254,29 @@ def testBaseConfig_SettersGetters(fncPath):
|
||||
|
||||
tstConf.setMainWinSize(70, 70)
|
||||
assert tstConf.mainWinSize == [70, 70]
|
||||
assert tstConf._mainWinSize == [70, 70]
|
||||
assert tstConf.mainWinSize == [70, 70]
|
||||
|
||||
tstConf.setMainWinSize(1200, 650)
|
||||
|
||||
# Welcome Window Size
|
||||
tstConf.setWelcomeWinSize(70, 70)
|
||||
assert tstConf.welcomeWinSize == [70, 70]
|
||||
assert tstConf._welcomeSize == [70, 70]
|
||||
assert tstConf.welcomeWinSize == [70, 70]
|
||||
|
||||
tstConf.setWelcomeWinSize(800, 500)
|
||||
|
||||
# Preferences Size
|
||||
tstConf.setPreferencesWinSize(70, 70)
|
||||
assert tstConf.preferencesWinSize == [70, 70]
|
||||
assert tstConf._prefsWinSize == [70, 70]
|
||||
assert tstConf.prefsWinSize == [70, 70]
|
||||
assert tstConf.prefsWinSize == [70, 70]
|
||||
|
||||
tstConf.setPreferencesWinSize(700, 615)
|
||||
|
||||
# Main Pane Splitter
|
||||
tstConf.setMainPanePos([200, 700])
|
||||
assert tstConf.mainPanePos == [200, 700]
|
||||
assert tstConf._mainPanePos == [200, 700]
|
||||
|
||||
tstConf.setMainPanePos([300, 800])
|
||||
|
||||
# View Pane Splitter
|
||||
tstConf.setViewPanePos([400, 250])
|
||||
assert tstConf.viewPanePos == [400, 250]
|
||||
assert tstConf._viewPanePos == [400, 250]
|
||||
|
||||
tstConf.setViewPanePos([500, 150])
|
||||
|
||||
# Outline Pane Splitter
|
||||
tstConf.setOutlinePanePos([400, 250])
|
||||
assert tstConf.outlinePanePos == [400, 250]
|
||||
assert tstConf._outlnPanePos == [400, 250]
|
||||
|
||||
tstConf.setOutlinePanePos([500, 150])
|
||||
|
||||
# Getters Only
|
||||
# ============
|
||||
|
||||
assert tstConf.getTextWidth(False) == 700
|
||||
assert tstConf.getTextWidth(True) == 800
|
||||
assert tstConf.getTextMargin() == 40
|
||||
assert tstConf.getTabWidth() == 40
|
||||
|
||||
|
||||
@pytest.mark.base
|
||||
|
||||
@@ -72,17 +72,16 @@ def testDlgPreferences_Main(qtbot, monkeypatch, nwGUI, tstPaths):
|
||||
prefs.close()
|
||||
|
||||
# Check Fallback Values
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(CONFIG, "hasEnchant", False)
|
||||
prefs = GuiPreferences(nwGUI)
|
||||
prefs.show()
|
||||
CONFIG.hasEnchant = False
|
||||
prefs = GuiPreferences(nwGUI)
|
||||
prefs.show()
|
||||
|
||||
# Check Spell Checking
|
||||
spelling = [prefs.spellLanguage.itemData(i) for i in range(prefs.spellLanguage.count())]
|
||||
assert len(spelling) == 1
|
||||
assert spelling == [""]
|
||||
# Check Spell Checking
|
||||
spelling = [prefs.spellLanguage.itemData(i) for i in range(prefs.spellLanguage.count())]
|
||||
assert len(spelling) == 1
|
||||
assert spelling == [""]
|
||||
|
||||
prefs.close()
|
||||
prefs.close()
|
||||
|
||||
# qtbot.stop()
|
||||
|
||||
@@ -138,13 +137,14 @@ def testDlgPreferences_Actions(qtbot, monkeypatch, nwGUI):
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def testDlgPreferences_Settings(qtbot, monkeypatch, nwGUI, tstPaths):
|
||||
def testDlgPreferences_Settings(qtbot, monkeypatch, nwGUI, fncPath, tstPaths):
|
||||
"""Test the preferences dialog settings."""
|
||||
spelling = [("en", "English [en]"), ("de", "Deutch [de]")]
|
||||
languages = [("en_GB", "British English"), ("en_US", "US English")]
|
||||
|
||||
monkeypatch.setattr(SHARED._spelling, "listDictionaries", lambda: spelling)
|
||||
monkeypatch.setattr(CONFIG, "listLanguages", lambda *a: languages)
|
||||
|
||||
(fncPath / "nw_en_US.qm").touch()
|
||||
(fncPath / "project_en_US.json").touch()
|
||||
CONFIG._nwLangPath = fncPath
|
||||
|
||||
prefs = GuiPreferences(nwGUI)
|
||||
with qtbot.waitExposed(prefs):
|
||||
|
||||
@@ -88,7 +88,12 @@ def testDlgProjSettings_SettingsPage(qtbot, monkeypatch, nwGUI, fncPath, projPat
|
||||
"""Test the settings page of the dialog."""
|
||||
languages = [("en", "English"), ("de", "German")]
|
||||
monkeypatch.setattr(SHARED._spelling, "listDictionaries", lambda *a: languages)
|
||||
monkeypatch.setattr(CONFIG, "listLanguages", lambda *a: languages)
|
||||
|
||||
(fncPath / "nw_en.qm").touch()
|
||||
(fncPath / "nw_de.qm").touch()
|
||||
(fncPath / "project_en.json").touch()
|
||||
(fncPath / "project_de.json").touch()
|
||||
CONFIG._nwLangPath = fncPath
|
||||
|
||||
# Create new project
|
||||
buildTestProject(nwGUI, projPath)
|
||||
|
||||
Reference in New Issue
Block a user