Clean up config file format, modify how projects are launched, and add broken theme setting handling
This commit is contained in:
@@ -161,9 +161,6 @@ def main(sysArgs=None):
|
||||
elif inOpt == "--testmode":
|
||||
testMode = True
|
||||
|
||||
# Set Config Options
|
||||
CONFIG.cmdOpen = cmdOpen
|
||||
|
||||
# Set Logging
|
||||
cHandle = logging.StreamHandler()
|
||||
cHandle.setFormatter(logging.Formatter(fmt=logFormat, style="{"))
|
||||
@@ -256,9 +253,7 @@ def main(sysArgs=None):
|
||||
# Launch main GUI
|
||||
CONFIG.initLocalisation(nwApp)
|
||||
nwGUI = GuiMain()
|
||||
if not nwGUI.hasProject:
|
||||
nwGUI.showProjectLoadDialog()
|
||||
nwGUI.releaseNotes()
|
||||
nwGUI.postLaunchTasks(cmdOpen)
|
||||
|
||||
sys.exit(nwApp.exec_())
|
||||
|
||||
|
||||
+152
-217
@@ -63,7 +63,7 @@ class Config:
|
||||
|
||||
self._confPath = confRoot.absolute() / self.appHandle # The user config location
|
||||
self._dataPath = dataRoot.absolute() / self.appHandle # The user data location
|
||||
self._lastPath = Path.home().absolute() # The user's last used path
|
||||
self._homePath = Path.home().absolute() # The user's home directory
|
||||
|
||||
self._appPath = Path(__file__).parent.absolute()
|
||||
self._appRoot = self._appPath.parent
|
||||
@@ -73,13 +73,12 @@ class Config:
|
||||
self._appPath = self._appRoot
|
||||
|
||||
# Runtime Settings and Variables
|
||||
self._hasError = False # True if the config class encountered an error
|
||||
self._errData = [] # List of error messages
|
||||
self._confChanged = False # True whenever the config has chenged, false after save
|
||||
self.cmdOpen = None # Path from command line for project to be opened on launch
|
||||
self._hasError = False # True if the config class encountered an error
|
||||
self._errData = [] # List of error messages
|
||||
|
||||
# Localisation Info
|
||||
self._qLocal = QLocale.system()
|
||||
# Localisation
|
||||
# Note that these paths must be strings
|
||||
self._qLocale = QLocale.system()
|
||||
self._qtTrans = {}
|
||||
self._qtLangPath = QLibraryInfo.location(QLibraryInfo.TranslationsPath)
|
||||
self._nwLangPath = str(self._appPath / "assets" / "i18n")
|
||||
@@ -94,34 +93,32 @@ class Config:
|
||||
self._recentProj = RecentProjects(self)
|
||||
|
||||
# General GUI Settings
|
||||
self.guiLang = self._qLocal.name()
|
||||
self.guiTheme = "" # GUI theme
|
||||
self.guiSyntax = "" # Syntax theme
|
||||
self.guiFont = "" # Defaults to system default font
|
||||
self.guiFontSize = 11 # Is overridden if system default is loaded
|
||||
self.guiScale = 1.0 # Set automatically by Theme class
|
||||
self.lastNotes = "0x0" # The latest release notes that have been shown
|
||||
|
||||
self.setDefaultGuiTheme()
|
||||
self.setDefaultSyntaxTheme()
|
||||
self.guiLocale = self._qLocale.name()
|
||||
self.guiTheme = "default" # GUI theme
|
||||
self.guiSyntax = "default_light" # Syntax theme
|
||||
self.guiFont = "" # Defaults to system default font in theme class
|
||||
self.guiFontSize = 11 # Is overridden if system default is loaded
|
||||
self.guiScale = 1.0 # Set automatically by Theme class
|
||||
self.hideVScroll = False # Hide vertical scroll bars on main widgets
|
||||
self.hideHScroll = False # Hide horizontal scroll bars on main widgets
|
||||
self.lastNotes = "0x0" # The latest release notes that have been shown
|
||||
self._lastPath = self._homePath # The user's last used path
|
||||
|
||||
# Size Settings
|
||||
self._winGeometry = [1200, 650]
|
||||
self._prefGeometry = [700, 615]
|
||||
self._projColWidth = [200, 60, 140]
|
||||
self._mainPanePos = [300, 800]
|
||||
self._viewPanePos = [500, 150]
|
||||
self._outlnPanePos = [500, 150]
|
||||
self.isFullScreen = False
|
||||
|
||||
# Feature Settings
|
||||
self.hideVScroll = False # Hide vertical scroll bars on main widgets
|
||||
self.hideHScroll = False # Hide horizontal scroll bars on main widgets
|
||||
self.emphLabels = True # Add emphasis to H1 and H2 item labels
|
||||
self._mainWinSize = [1200, 650] # Last size of the main GUI window
|
||||
self._prefsWinSize = [700, 615] # Last size of the Preferences dialog
|
||||
self._projLoadCols = [280, 60, 160] # Last columns withs of the Project Load 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
|
||||
|
||||
# Project Settings
|
||||
self.autoSaveProj = 60 # Interval for auto-saving project in seconds
|
||||
self.autoSaveDoc = 30 # Interval for auto-saving document in seconds
|
||||
self.autoSaveProj = 60 # Interval for auto-saving project, in seconds
|
||||
self.autoSaveDoc = 30 # Interval for auto-saving document, in seconds
|
||||
self.emphLabels = True # Add emphasis to H1 and H2 item labels
|
||||
self._backupPath = None # Backup path to use, can be none
|
||||
self.backupOnClose = False # Flag for running automatic backups
|
||||
self.askBeforeBackup = True # Flag for asking before running automatic backup
|
||||
|
||||
# Text Editor Settings
|
||||
self.textFont = None # Editor font
|
||||
@@ -173,6 +170,12 @@ class Config:
|
||||
# Spell Checking Settings
|
||||
self.spellLanguage = "en"
|
||||
|
||||
# State
|
||||
self.isFullScreen = False # Last fullscreen state
|
||||
self.showRefPanel = True # The reference panel for the viewer is visible
|
||||
self.viewComments = True # Comments are shown in the viewer
|
||||
self.viewSynopsis = True # Synopsis is shown in the viewer
|
||||
|
||||
# Search Bar Switches
|
||||
self.searchCase = False
|
||||
self.searchWord = False
|
||||
@@ -181,16 +184,6 @@ class Config:
|
||||
self.searchNextFile = False
|
||||
self.searchMatchCap = False
|
||||
|
||||
# Backup Settings
|
||||
self._backupPath = None
|
||||
self.backupOnClose = False
|
||||
self.askBeforeBackup = True
|
||||
|
||||
# State
|
||||
self.showRefPanel = True # The reference panel for the viewer is visible
|
||||
self.viewComments = True # Comments are shown in the viewer
|
||||
self.viewSynopsis = True # Synopsis is shown in the viewer
|
||||
|
||||
# System and App Information
|
||||
# ==========================
|
||||
|
||||
@@ -259,15 +252,15 @@ class Config:
|
||||
|
||||
@property
|
||||
def mainWinSize(self):
|
||||
return [int(x*self.guiScale) for x in self._winGeometry]
|
||||
return [int(x*self.guiScale) for x in self._mainWinSize]
|
||||
|
||||
@property
|
||||
def preferencesWinSize(self):
|
||||
return [int(x*self.guiScale) for x in self._prefGeometry]
|
||||
return [int(x*self.guiScale) for x in self._prefsWinSize]
|
||||
|
||||
@property
|
||||
def projLoadColWidths(self):
|
||||
return [int(x*self.guiScale) for x in self._projColWidth]
|
||||
return [int(x*self.guiScale) for x in self._projLoadCols]
|
||||
|
||||
@property
|
||||
def mainPanePos(self):
|
||||
@@ -281,6 +274,25 @@ class Config:
|
||||
def outlinePanePos(self):
|
||||
return [int(x*self.guiScale) for x in self._outlnPanePos]
|
||||
|
||||
##
|
||||
# Getters
|
||||
##
|
||||
|
||||
def getTextWidth(self, focusMode=False):
|
||||
"""Get the text with for the correct editor mode."""
|
||||
if focusMode:
|
||||
return self.pxInt(max(self.focusWidth, 200))
|
||||
else:
|
||||
return self.pxInt(max(self.textWidth, 200))
|
||||
|
||||
def getTextMargin(self):
|
||||
"""Get the scaled text margin."""
|
||||
return self.pxInt(max(self.textMargin, 0))
|
||||
|
||||
def getTabWidth(self):
|
||||
"""Get the scaled tab width."""
|
||||
return self.pxInt(max(self.tabWidth, 0))
|
||||
|
||||
##
|
||||
# Setters
|
||||
##
|
||||
@@ -293,48 +305,36 @@ class Config:
|
||||
"""
|
||||
newWidth = int(newWidth/self.guiScale)
|
||||
newHeight = int(newHeight/self.guiScale)
|
||||
if abs(self._winGeometry[0] - newWidth) > 5:
|
||||
self._winGeometry[0] = newWidth
|
||||
self._confChanged = True
|
||||
if abs(self._winGeometry[1] - newHeight) > 5:
|
||||
self._winGeometry[1] = newHeight
|
||||
self._confChanged = True
|
||||
if abs(self._mainWinSize[0] - newWidth) > 5:
|
||||
self._mainWinSize[0] = newWidth
|
||||
if abs(self._mainWinSize[1] - newHeight) > 5:
|
||||
self._mainWinSize[1] = newHeight
|
||||
return
|
||||
|
||||
def setPreferencesWinSize(self, newWidth, newHeight):
|
||||
"""Sat the size of the Preferences dialog window.
|
||||
"""
|
||||
self._prefGeometry[0] = int(newWidth/self.guiScale)
|
||||
self._prefGeometry[1] = int(newHeight/self.guiScale)
|
||||
self._confChanged = True
|
||||
"""Set the size of the Preferences dialog window."""
|
||||
self._prefsWinSize[0] = int(newWidth/self.guiScale)
|
||||
self._prefsWinSize[1] = int(newHeight/self.guiScale)
|
||||
return
|
||||
|
||||
def setProjLoadColWidths(self, colWidths):
|
||||
"""Set the column widths of the Load Project dialog.
|
||||
"""
|
||||
self._projColWidth = [int(x/self.guiScale) for x in colWidths]
|
||||
self._confChanged = True
|
||||
"""Set the column widths of the Load Project dialog."""
|
||||
self._projLoadCols = [int(x/self.guiScale) for x in colWidths]
|
||||
return
|
||||
|
||||
def setMainPanePos(self, panePos):
|
||||
"""Set the position of the main GUI splitter.
|
||||
"""
|
||||
"""Set the position of the main GUI splitter."""
|
||||
self._mainPanePos = [int(x/self.guiScale) for x in panePos]
|
||||
self._confChanged = True
|
||||
return
|
||||
|
||||
def setViewPanePos(self, panePos):
|
||||
"""Set the position of the viewer meta data splitter.
|
||||
"""
|
||||
"""Set the position of the viewer meta data splitter."""
|
||||
self._viewPanePos = [int(x/self.guiScale) for x in panePos]
|
||||
self._confChanged = True
|
||||
return
|
||||
|
||||
def setOutlinePanePos(self, panePos):
|
||||
"""Set the position of the outline details splitter.
|
||||
"""
|
||||
"""Set the position of the outline details splitter."""
|
||||
self._outlnPanePos = [int(x/self.guiScale) for x in panePos]
|
||||
self._confChanged = True
|
||||
return
|
||||
|
||||
def setLastPath(self, lastPath):
|
||||
@@ -342,7 +342,7 @@ class Config:
|
||||
path is not a folder, the parent of the path is used instead.
|
||||
"""
|
||||
if isinstance(lastPath, (str, Path)):
|
||||
lastPath = Path(lastPath)
|
||||
lastPath = checkPath(lastPath, self._homePath)
|
||||
if not lastPath.is_dir():
|
||||
lastPath = lastPath.parent
|
||||
if lastPath.is_dir():
|
||||
@@ -351,15 +351,10 @@ class Config:
|
||||
return
|
||||
|
||||
def setBackupPath(self, backupPath):
|
||||
"""Set the current backup path.
|
||||
"""
|
||||
"""Set the current backup path."""
|
||||
self._backupPath = checkPath(backupPath, None)
|
||||
return
|
||||
|
||||
def setConfigChanged(self, value):
|
||||
self._confChanged = bool(value)
|
||||
return
|
||||
|
||||
##
|
||||
# Methods
|
||||
##
|
||||
@@ -377,15 +372,13 @@ class Config:
|
||||
return int(theSize/self.guiScale)
|
||||
|
||||
def dataPath(self, target=None):
|
||||
"""Return a path in the data folder.
|
||||
"""
|
||||
"""Return a path in the data folder."""
|
||||
if isinstance(target, str):
|
||||
return self._dataPath / target
|
||||
return self._dataPath
|
||||
|
||||
def assetPath(self, target=None):
|
||||
"""Return a path in the assets folder.
|
||||
"""
|
||||
"""Return a path in the assets folder."""
|
||||
if isinstance(target, str):
|
||||
return self._appPath / "assets" / target
|
||||
return self._appPath / "assets"
|
||||
@@ -396,11 +389,10 @@ class Config:
|
||||
if isinstance(self._lastPath, Path):
|
||||
if self._lastPath.is_dir():
|
||||
return self._lastPath
|
||||
return Path.home().absolute()
|
||||
return self._homePath
|
||||
|
||||
def backupPath(self):
|
||||
"""Return the backup path.
|
||||
"""
|
||||
"""Return the backup path."""
|
||||
if isinstance(self._backupPath, Path):
|
||||
if self._backupPath.is_dir():
|
||||
return self._backupPath
|
||||
@@ -415,6 +407,33 @@ class Config:
|
||||
self._errData = []
|
||||
return errMessage
|
||||
|
||||
def listLanguages(self, lngSet):
|
||||
"""List localisation files in the i18n folder. The default GUI
|
||||
language is British English (en_GB).
|
||||
"""
|
||||
if lngSet == self.LANG_NW:
|
||||
fPre = "nw_"
|
||||
fExt = ".qm"
|
||||
langList = {"en_GB": QLocale("en_GB").nativeLanguageName().title()}
|
||||
elif lngSet == self.LANG_PROJ:
|
||||
fPre = "project_"
|
||||
fExt = ".json"
|
||||
langList = {"en_GB": QLocale("en_GB").nativeLanguageName().title()}
|
||||
else:
|
||||
return []
|
||||
|
||||
for qmFile in Path(self._nwLangPath).iterdir():
|
||||
qmName = qmFile.name
|
||||
if not (qmFile.is_file() and qmName.startswith(fPre) and qmName.endswith(fExt)):
|
||||
continue
|
||||
|
||||
qmLang = qmName[len(fPre):-len(fExt)]
|
||||
qmName = QLocale(qmLang).nativeLanguageName().title()
|
||||
if qmLang and qmName and qmLang != "en_GB":
|
||||
langList[qmLang] = qmName
|
||||
|
||||
return sorted(langList.items(), key=lambda x: x[0])
|
||||
|
||||
##
|
||||
# Config Actions
|
||||
##
|
||||
@@ -464,54 +483,26 @@ class Config:
|
||||
def initLocalisation(self, nwApp):
|
||||
"""Initialise the localisation of the GUI.
|
||||
"""
|
||||
self._qLocal = QLocale(self.guiLang)
|
||||
QLocale.setDefault(self._qLocal)
|
||||
self._qLocale = QLocale(self.guiLocale)
|
||||
QLocale.setDefault(self._qLocale)
|
||||
self._qtTrans = {}
|
||||
|
||||
langList = [
|
||||
(self._qtLangPath, "qtbase"), # Qt 5.x
|
||||
(self._nwLangPath, "qtbase"), # Alternative Qt 5.x
|
||||
(self._nwLangPath, "nw"), # novelWriter
|
||||
]
|
||||
for lngPath, lngBase in langList:
|
||||
for lngCode in self._qLocal.uiLanguages():
|
||||
for lngCode in self._qLocale.uiLanguages():
|
||||
qTrans = QTranslator()
|
||||
lngFile = "%s_%s" % (lngBase, lngCode.replace("-", "_"))
|
||||
if lngFile not in self._qtTrans:
|
||||
if qTrans.load(lngFile, str(lngPath)):
|
||||
logger.debug("Loaded: %s/%s", lngPath, lngFile)
|
||||
if qTrans.load(lngFile, lngPath):
|
||||
logger.debug("Loaded: %s.qm", lngFile)
|
||||
nwApp.installTranslator(qTrans)
|
||||
self._qtTrans[lngFile] = qTrans
|
||||
|
||||
return
|
||||
|
||||
def listLanguages(self, lngSet):
|
||||
"""List localisation files in the i18n folder. The default GUI
|
||||
language is British English (en_GB).
|
||||
"""
|
||||
if lngSet == self.LANG_NW:
|
||||
fPre = "nw_"
|
||||
fExt = ".qm"
|
||||
langList = {"en_GB": QLocale("en_GB").nativeLanguageName().title()}
|
||||
elif lngSet == self.LANG_PROJ:
|
||||
fPre = "project_"
|
||||
fExt = ".json"
|
||||
langList = {"en_GB": QLocale("en_GB").nativeLanguageName().title()}
|
||||
else:
|
||||
return []
|
||||
|
||||
for qmFile in Path(self._nwLangPath).iterdir():
|
||||
qmName = qmFile.name
|
||||
if not (qmFile.is_file() and qmName.startswith(fPre) and qmName.endswith(fExt)):
|
||||
continue
|
||||
|
||||
qmLang = qmName[len(fPre):-len(fExt)]
|
||||
qmName = QLocale(qmLang).nativeLanguageName().title()
|
||||
if qmLang and qmName and qmLang != "en_GB":
|
||||
langList[qmLang] = qmName
|
||||
|
||||
return sorted(langList.items(), key=lambda x: x[0])
|
||||
|
||||
def loadConfig(self):
|
||||
"""Load preferences from file and replace default settings.
|
||||
"""
|
||||
@@ -534,28 +525,31 @@ class Config:
|
||||
cnfSec = "Main"
|
||||
self.guiTheme = theConf.rdStr(cnfSec, "theme", self.guiTheme)
|
||||
self.guiSyntax = theConf.rdStr(cnfSec, "syntax", self.guiSyntax)
|
||||
self.guiFont = theConf.rdStr(cnfSec, "guifont", self.guiFont)
|
||||
self.guiFontSize = theConf.rdInt(cnfSec, "guifontsize", self.guiFontSize)
|
||||
self.lastNotes = theConf.rdStr(cnfSec, "lastnotes", self.lastNotes)
|
||||
self.guiLang = theConf.rdStr(cnfSec, "guilang", self.guiLang)
|
||||
self.guiFont = theConf.rdStr(cnfSec, "font", self.guiFont)
|
||||
self.guiFontSize = theConf.rdInt(cnfSec, "fontsize", self.guiFontSize)
|
||||
self.guiLocale = theConf.rdStr(cnfSec, "localisation", self.guiLocale)
|
||||
self.hideVScroll = theConf.rdBool(cnfSec, "hidevscroll", self.hideVScroll)
|
||||
self.hideHScroll = theConf.rdBool(cnfSec, "hidehscroll", self.hideHScroll)
|
||||
self.lastNotes = theConf.rdStr(cnfSec, "lastnotes", self.lastNotes)
|
||||
self._lastPath = theConf.rdPath(cnfSec, "lastpath", self._lastPath)
|
||||
|
||||
# Sizes
|
||||
cnfSec = "Sizes"
|
||||
self._winGeometry = theConf.rdIntList(cnfSec, "geometry", self._winGeometry)
|
||||
self._prefGeometry = theConf.rdIntList(cnfSec, "preferences", self._prefGeometry)
|
||||
self._projColWidth = theConf.rdIntList(cnfSec, "projcols", self._projColWidth)
|
||||
self._mainWinSize = theConf.rdIntList(cnfSec, "mainwindow", self._mainWinSize)
|
||||
self._prefsWinSize = theConf.rdIntList(cnfSec, "preferences", self._prefsWinSize)
|
||||
self._projLoadCols = theConf.rdIntList(cnfSec, "projloadcols", self._projLoadCols)
|
||||
self._mainPanePos = theConf.rdIntList(cnfSec, "mainpane", self._mainPanePos)
|
||||
self._viewPanePos = theConf.rdIntList(cnfSec, "viewpane", self._viewPanePos)
|
||||
self._outlnPanePos = theConf.rdIntList(cnfSec, "outlinepane", self._outlnPanePos)
|
||||
self.isFullScreen = theConf.rdBool(cnfSec, "fullscreen", self.isFullScreen)
|
||||
|
||||
# Project
|
||||
cnfSec = "Project"
|
||||
self.autoSaveProj = theConf.rdInt(cnfSec, "autosaveproject", self.autoSaveProj)
|
||||
self.autoSaveDoc = theConf.rdInt(cnfSec, "autosavedoc", self.autoSaveDoc)
|
||||
self.emphLabels = theConf.rdBool(cnfSec, "emphlabels", self.emphLabels)
|
||||
self.autoSaveProj = theConf.rdInt(cnfSec, "autosaveproject", self.autoSaveProj)
|
||||
self.autoSaveDoc = theConf.rdInt(cnfSec, "autosavedoc", self.autoSaveDoc)
|
||||
self.emphLabels = theConf.rdBool(cnfSec, "emphlabels", self.emphLabels)
|
||||
self._backupPath = theConf.rdPath(cnfSec, "backuppath", self._backupPath)
|
||||
self.backupOnClose = theConf.rdBool(cnfSec, "backuponclose", self.backupOnClose)
|
||||
self.askBeforeBackup = theConf.rdBool(cnfSec, "askbeforebackup", self.askBeforeBackup)
|
||||
|
||||
# Editor
|
||||
cnfSec = "Editor"
|
||||
@@ -596,14 +590,9 @@ class Config:
|
||||
self.stopWhenIdle = theConf.rdBool(cnfSec, "stopwhenidle", self.stopWhenIdle)
|
||||
self.userIdleTime = theConf.rdInt(cnfSec, "useridletime", self.userIdleTime)
|
||||
|
||||
# Backup
|
||||
cnfSec = "Backup"
|
||||
self._backupPath = theConf.rdPath(cnfSec, "backuppath", self._backupPath)
|
||||
self.backupOnClose = theConf.rdBool(cnfSec, "backuponclose", self.backupOnClose)
|
||||
self.askBeforeBackup = theConf.rdBool(cnfSec, "askbeforebackup", self.askBeforeBackup)
|
||||
|
||||
# State
|
||||
cnfSec = "State"
|
||||
self.isFullScreen = theConf.rdBool(cnfSec, "fullscreen", self.isFullScreen)
|
||||
self.showRefPanel = theConf.rdBool(cnfSec, "showrefpanel", self.showRefPanel)
|
||||
self.viewComments = theConf.rdBool(cnfSec, "viewcomments", self.viewComments)
|
||||
self.viewSynopsis = theConf.rdBool(cnfSec, "viewsynopsis", self.viewSynopsis)
|
||||
@@ -614,9 +603,14 @@ class Config:
|
||||
self.searchNextFile = theConf.rdBool(cnfSec, "searchnextfile", self.searchNextFile)
|
||||
self.searchMatchCap = theConf.rdBool(cnfSec, "searchmatchcap", self.searchMatchCap)
|
||||
|
||||
# Path
|
||||
cnfSec = "Path"
|
||||
self._lastPath = theConf.rdPath(cnfSec, "lastpath", self._lastPath)
|
||||
# Deprecated Settings or Locations as of 2.0
|
||||
# These will be loaded for a few minor releases until the users have converted them
|
||||
self.guiFont = theConf.rdStr("Main", "guifont", self.guiFont)
|
||||
self.guiFontSize = theConf.rdInt("Main", "guifontsize", self.guiFontSize)
|
||||
self.guiLocale = theConf.rdStr("Main", "guilang", self.guiLocale)
|
||||
self._backupPath = theConf.rdPath("Backup", "backuppath", self._backupPath)
|
||||
self.backupOnClose = theConf.rdBool("Backup", "backuponclose", self.backupOnClose)
|
||||
self.askBeforeBackup = theConf.rdBool("Backup", "askbeforebackup", self.askBeforeBackup)
|
||||
|
||||
# Check Certain Values for None
|
||||
self.spellLanguage = self._checkNone(self.spellLanguage)
|
||||
@@ -639,32 +633,38 @@ class Config:
|
||||
|
||||
theConf = NWConfigParser()
|
||||
|
||||
theConf["Meta"] = {
|
||||
"timestamp": formatTimeStamp(time()),
|
||||
}
|
||||
|
||||
theConf["Main"] = {
|
||||
"timestamp": formatTimeStamp(time()),
|
||||
"theme": str(self.guiTheme),
|
||||
"syntax": str(self.guiSyntax),
|
||||
"guifont": str(self.guiFont),
|
||||
"guifontsize": str(self.guiFontSize),
|
||||
"lastnotes": str(self.lastNotes),
|
||||
"guilang": str(self.guiLang),
|
||||
"hidevscroll": str(self.hideVScroll),
|
||||
"hidehscroll": str(self.hideHScroll),
|
||||
"theme": str(self.guiTheme),
|
||||
"syntax": str(self.guiSyntax),
|
||||
"font": str(self.guiFont),
|
||||
"fontsize": str(self.guiFontSize),
|
||||
"localisation": str(self.guiLocale),
|
||||
"hidevscroll": str(self.hideVScroll),
|
||||
"hidehscroll": str(self.hideHScroll),
|
||||
"lastnotes": str(self.lastNotes),
|
||||
"lastpath": str(self._lastPath),
|
||||
}
|
||||
|
||||
theConf["Sizes"] = {
|
||||
"geometry": self._packList(self._winGeometry),
|
||||
"preferences": self._packList(self._prefGeometry),
|
||||
"projcols": self._packList(self._projColWidth),
|
||||
"mainpane": self._packList(self._mainPanePos),
|
||||
"viewpane": self._packList(self._viewPanePos),
|
||||
"outlinepane": self._packList(self._outlnPanePos),
|
||||
"fullscreen": str(self.isFullScreen),
|
||||
"mainwindow": self._packList(self._mainWinSize),
|
||||
"preferences": self._packList(self._prefsWinSize),
|
||||
"projloadcols": self._packList(self._projLoadCols),
|
||||
"mainpane": self._packList(self._mainPanePos),
|
||||
"viewpane": self._packList(self._viewPanePos),
|
||||
"outlinepane": self._packList(self._outlnPanePos),
|
||||
}
|
||||
|
||||
theConf["Project"] = {
|
||||
"autosaveproject": str(self.autoSaveProj),
|
||||
"autosavedoc": str(self.autoSaveDoc),
|
||||
"emphlabels": str(self.emphLabels),
|
||||
"backuppath": str(self._backupPath or ""),
|
||||
"backuponclose": str(self.backupOnClose),
|
||||
"askbeforebackup": str(self.askBeforeBackup),
|
||||
}
|
||||
|
||||
theConf["Editor"] = {
|
||||
@@ -706,13 +706,8 @@ class Config:
|
||||
"useridletime": str(self.userIdleTime),
|
||||
}
|
||||
|
||||
theConf["Backup"] = {
|
||||
"backuppath": str(self._backupPath or ""),
|
||||
"backuponclose": str(self.backupOnClose),
|
||||
"askbeforebackup": str(self.askBeforeBackup),
|
||||
}
|
||||
|
||||
theConf["State"] = {
|
||||
"fullscreen": str(self.isFullScreen),
|
||||
"showrefpanel": str(self.showRefPanel),
|
||||
"viewcomments": str(self.viewComments),
|
||||
"viewsynopsis": str(self.viewSynopsis),
|
||||
@@ -724,16 +719,11 @@ class Config:
|
||||
"searchmatchcap": str(self.searchMatchCap),
|
||||
}
|
||||
|
||||
theConf["Path"] = {
|
||||
"lastpath": str(self._lastPath),
|
||||
}
|
||||
|
||||
# Write config file
|
||||
cnfPath = self._confPath / nwFiles.CONF_FILE
|
||||
try:
|
||||
with open(cnfPath, mode="w", encoding="utf-8") as outFile:
|
||||
theConf.write(outFile)
|
||||
self._confChanged = False
|
||||
except Exception as exc:
|
||||
logger.error("Could not save config file")
|
||||
logException()
|
||||
@@ -744,61 +734,6 @@ class Config:
|
||||
|
||||
return True
|
||||
|
||||
##
|
||||
# Setters
|
||||
##
|
||||
|
||||
def setShowRefPanel(self, checkState):
|
||||
"""Set the visibility state of the reference panel.
|
||||
"""
|
||||
self.showRefPanel = checkState
|
||||
self._confChanged = True
|
||||
return
|
||||
|
||||
def setViewComments(self, viewState):
|
||||
"""Set the visibility state of comments in the viewer.
|
||||
"""
|
||||
self.viewComments = viewState
|
||||
self._confChanged = True
|
||||
return
|
||||
|
||||
def setViewSynopsis(self, viewState):
|
||||
"""Set the visibility state of synopsis comments in the viewer.
|
||||
"""
|
||||
self.viewSynopsis = viewState
|
||||
self._confChanged = True
|
||||
return
|
||||
|
||||
##
|
||||
# Default Setters
|
||||
##
|
||||
|
||||
def setDefaultGuiTheme(self):
|
||||
"""Reset the GUI theme to default value.
|
||||
"""
|
||||
self.guiTheme = "default"
|
||||
|
||||
def setDefaultSyntaxTheme(self):
|
||||
"""Reset the syntax theme to default value.
|
||||
"""
|
||||
self.guiSyntax = "default_light"
|
||||
|
||||
##
|
||||
# Getters
|
||||
##
|
||||
|
||||
def getTextWidth(self, focusMode=False):
|
||||
if focusMode:
|
||||
return self.pxInt(max(self.focusWidth, 200))
|
||||
else:
|
||||
return self.pxInt(max(self.textWidth, 200))
|
||||
|
||||
def getTextMargin(self):
|
||||
return self.pxInt(max(self.textMargin, 0))
|
||||
|
||||
def getTabWidth(self):
|
||||
return self.pxInt(max(self.tabWidth, 0))
|
||||
|
||||
##
|
||||
# Internal Functions
|
||||
##
|
||||
|
||||
@@ -125,6 +125,7 @@ class GuiPreferences(PagedDialog):
|
||||
self.tabQuote.saveValues()
|
||||
|
||||
self._saveWindowSize()
|
||||
self.mainConf.saveConfig()
|
||||
self.accept()
|
||||
|
||||
return
|
||||
@@ -170,18 +171,18 @@ class GuiPreferencesGeneral(QWidget):
|
||||
minWidth = self.mainConf.pxInt(200)
|
||||
|
||||
# Select Locale
|
||||
self.guiLang = QComboBox()
|
||||
self.guiLang.setMinimumWidth(minWidth)
|
||||
self.guiLocale = QComboBox()
|
||||
self.guiLocale.setMinimumWidth(minWidth)
|
||||
theLangs = self.mainConf.listLanguages(self.mainConf.LANG_NW)
|
||||
for lang, langName in theLangs:
|
||||
self.guiLang.addItem(langName, lang)
|
||||
langIdx = self.guiLang.findData(self.mainConf.guiLang)
|
||||
self.guiLocale.addItem(langName, lang)
|
||||
langIdx = self.guiLocale.findData(self.mainConf.guiLocale)
|
||||
if langIdx != -1:
|
||||
self.guiLang.setCurrentIndex(langIdx)
|
||||
self.guiLocale.setCurrentIndex(langIdx)
|
||||
|
||||
self.mainForm.addRow(
|
||||
self.tr("Main GUI language"),
|
||||
self.guiLang,
|
||||
self.guiLocale,
|
||||
self.tr("Requires restart to take effect.")
|
||||
)
|
||||
|
||||
@@ -286,7 +287,7 @@ class GuiPreferencesGeneral(QWidget):
|
||||
def saveValues(self):
|
||||
"""Save the values set for this tab.
|
||||
"""
|
||||
guiLang = self.guiLang.currentData()
|
||||
guiLocale = self.guiLocale.currentData()
|
||||
guiTheme = self.guiTheme.currentData()
|
||||
guiSyntax = self.guiSyntax.currentData()
|
||||
guiFont = self.guiFont.text()
|
||||
@@ -296,12 +297,12 @@ class GuiPreferencesGeneral(QWidget):
|
||||
# Update Flags
|
||||
self.prefsGui._updateTheme |= self.mainConf.guiTheme != guiTheme
|
||||
self.prefsGui._updateSyntax |= self.mainConf.guiSyntax != guiSyntax
|
||||
self.prefsGui._needsRestart |= self.mainConf.guiLang != guiLang
|
||||
self.prefsGui._needsRestart |= self.mainConf.guiLocale != guiLocale
|
||||
self.prefsGui._needsRestart |= self.mainConf.guiFont != guiFont
|
||||
self.prefsGui._needsRestart |= self.mainConf.guiFontSize != guiFontSize
|
||||
self.prefsGui._refreshTree |= self.mainConf.emphLabels != emphLabels
|
||||
|
||||
self.mainConf.guiLang = guiLang
|
||||
self.mainConf.guiLocale = guiLocale
|
||||
self.mainConf.guiTheme = guiTheme
|
||||
self.mainConf.guiSyntax = guiSyntax
|
||||
self.mainConf.guiFont = guiFont
|
||||
@@ -311,8 +312,6 @@ class GuiPreferencesGeneral(QWidget):
|
||||
self.mainConf.hideVScroll = self.hideVScroll.isChecked()
|
||||
self.mainConf.hideHScroll = self.hideHScroll.isChecked()
|
||||
|
||||
self.mainConf.setConfigChanged(True)
|
||||
|
||||
return
|
||||
|
||||
##
|
||||
@@ -458,8 +457,6 @@ class GuiPreferencesProjects(QWidget):
|
||||
self.mainConf.stopWhenIdle = self.stopWhenIdle.isChecked()
|
||||
self.mainConf.userIdleTime = round(self.userIdleTime.value() * 60)
|
||||
|
||||
self.mainConf.setConfigChanged(True)
|
||||
|
||||
return
|
||||
|
||||
##
|
||||
@@ -629,8 +626,6 @@ class GuiPreferencesDocuments(QWidget):
|
||||
self.mainConf.textMargin = self.textMargin.value()
|
||||
self.mainConf.tabWidth = self.tabWidth.value()
|
||||
|
||||
self.mainConf.setConfigChanged(True)
|
||||
|
||||
return
|
||||
|
||||
##
|
||||
@@ -820,8 +815,6 @@ class GuiPreferencesEditor(QWidget):
|
||||
self.mainConf.autoScroll = self.autoScroll.isChecked()
|
||||
self.mainConf.autoScrollPos = self.autoScrollPos.value()
|
||||
|
||||
self.mainConf.setConfigChanged(True)
|
||||
|
||||
return
|
||||
|
||||
# END Class GuiPreferencesEditor
|
||||
@@ -911,8 +904,6 @@ class GuiPreferencesSyntax(QWidget):
|
||||
# Text Errors
|
||||
self.mainConf.showMultiSpaces = self.showMultiSpaces.isChecked()
|
||||
|
||||
self.mainConf.setConfigChanged(True)
|
||||
|
||||
return
|
||||
|
||||
##
|
||||
@@ -1065,8 +1056,6 @@ class GuiPreferencesAutomation(QWidget):
|
||||
self.mainConf.fmtPadAfter = self.fmtPadAfter.text().strip()
|
||||
self.mainConf.fmtPadThin = self.fmtPadThin.isChecked()
|
||||
|
||||
self.mainConf.setConfigChanged(True)
|
||||
|
||||
return
|
||||
|
||||
##
|
||||
@@ -1185,9 +1174,6 @@ class GuiPreferencesQuotes(QWidget):
|
||||
self.mainConf.fmtSingleQuotes[1] = self.quoteSym["SC"].text()
|
||||
self.mainConf.fmtDoubleQuotes[0] = self.quoteSym["DO"].text()
|
||||
self.mainConf.fmtDoubleQuotes[1] = self.quoteSym["DC"].text()
|
||||
|
||||
self.mainConf.setConfigChanged(True)
|
||||
|
||||
return
|
||||
|
||||
##
|
||||
|
||||
@@ -1148,7 +1148,7 @@ class GuiDocViewFooter(QWidget):
|
||||
def _doToggleComments(self, theState):
|
||||
"""Toggle the view comment button and reload the document.
|
||||
"""
|
||||
self.mainConf.setViewComments(theState)
|
||||
self.mainConf.viewComments = theState
|
||||
self.docViewer.reloadText()
|
||||
return
|
||||
|
||||
@@ -1156,7 +1156,7 @@ class GuiDocViewFooter(QWidget):
|
||||
def _doToggleSynopsis(self, theState):
|
||||
"""Toggle the view synopsis button and reload the document.
|
||||
"""
|
||||
self.mainConf.setViewSynopsis(theState)
|
||||
self.mainConf.viewSynopsis = theState
|
||||
self.docViewer.reloadText()
|
||||
return
|
||||
|
||||
|
||||
@@ -185,9 +185,14 @@ class GuiTheme:
|
||||
"""Load the currently specified GUI theme.
|
||||
"""
|
||||
guiTheme = self.mainConf.guiTheme
|
||||
if guiTheme not in self._availThemes:
|
||||
logger.error("Could not find GUI theme '%s'", guiTheme)
|
||||
guiTheme = "default"
|
||||
self.mainConf.guiTheme = guiTheme
|
||||
|
||||
themeFile = self._availThemes.get(guiTheme, None)
|
||||
if themeFile is None:
|
||||
logger.error("Could not find GUI theme '%s'", guiTheme)
|
||||
logger.error("Could not load GUI theme")
|
||||
return False
|
||||
|
||||
# Config File
|
||||
@@ -266,9 +271,14 @@ class GuiTheme:
|
||||
"""Load the currently specified syntax highlighter theme.
|
||||
"""
|
||||
guiSyntax = self.mainConf.guiSyntax
|
||||
if guiSyntax not in self._availSyntax:
|
||||
logger.error("Could not find syntax theme '%s'", guiSyntax)
|
||||
guiSyntax = "default_light"
|
||||
self.mainConf.guiSyntax = guiSyntax
|
||||
|
||||
syntaxFile = self._availSyntax.get(guiSyntax, None)
|
||||
if syntaxFile is None:
|
||||
logger.error("Could not find syntax theme '%s'", guiSyntax)
|
||||
logger.error("Could not load syntax theme")
|
||||
return False
|
||||
|
||||
logger.info("Loading syntax theme '%s'", guiSyntax)
|
||||
|
||||
+14
-10
@@ -79,7 +79,7 @@ class GuiMain(QMainWindow):
|
||||
logger.info("Qt5: %s (%d)", self.mainConf.verQtString, self.mainConf.verQtValue)
|
||||
logger.info("PyQt5: %s (%d)", self.mainConf.verPyQtString, self.mainConf.verPyQtValue)
|
||||
logger.info("Python: %s (0x%x)", self.mainConf.verPyString, self.mainConf.verPyHexVal)
|
||||
logger.info("GUI Language: %s", self.mainConf.guiLang)
|
||||
logger.info("GUI Language: %s", self.mainConf.guiLocale)
|
||||
|
||||
# Core Classes
|
||||
# ============
|
||||
@@ -290,11 +290,6 @@ class GuiMain(QMainWindow):
|
||||
"and make sure you take regular backups."
|
||||
), nwAlert.WARN)
|
||||
|
||||
# If a project path was provided at command line, open it
|
||||
if self.mainConf.cmdOpen is not None:
|
||||
logger.debug("Opening project from additional command line option")
|
||||
self.openProject(self.mainConf.cmdOpen)
|
||||
|
||||
logger.info("novelWriter is ready ...")
|
||||
self.setStatus(self.tr("novelWriter is ready ..."))
|
||||
|
||||
@@ -327,13 +322,22 @@ class GuiMain(QMainWindow):
|
||||
self.asDocTimer.setInterval(int(self.mainConf.autoSaveDoc*1000))
|
||||
return True
|
||||
|
||||
def releaseNotes(self):
|
||||
"""Determine whether release notes need to be shown, and show
|
||||
them by calling the About dialog.
|
||||
def postLaunchTasks(self, cmdOpen):
|
||||
"""This function is called after the main window is created to
|
||||
determine what to open or show after initialisation.
|
||||
"""
|
||||
if cmdOpen:
|
||||
logger.info("Command line path: %s", cmdOpen)
|
||||
self.openProject(cmdOpen)
|
||||
|
||||
if not self.hasProject:
|
||||
self.showProjectLoadDialog()
|
||||
|
||||
# Determine whether release notes need to be shown or not
|
||||
if hexToInt(self.mainConf.lastNotes) < hexToInt(novelwriter.__hexversion__):
|
||||
self.mainConf.lastNotes = novelwriter.__hexversion__
|
||||
self.showAboutNWDialog(showNotes=True)
|
||||
|
||||
return
|
||||
|
||||
##
|
||||
@@ -1173,7 +1177,7 @@ class GuiMain(QMainWindow):
|
||||
if self.viewMeta.isVisible():
|
||||
self.mainConf.setViewPanePos(self.splitView.sizes())
|
||||
|
||||
self.mainConf.setShowRefPanel(self.viewMeta.isVisible())
|
||||
self.mainConf.showRefPanel = self.viewMeta.isVisible()
|
||||
if not self.mainConf.isFullScreen:
|
||||
self.mainConf.setMainWinSize(self.width(), self.height())
|
||||
|
||||
|
||||
+2
-2
@@ -113,7 +113,7 @@ def tmpConf(tmpPath):
|
||||
theConf = Config()
|
||||
theConf.initConfig(tmpPath, tmpPath)
|
||||
theConf.setLastPath(tmpPath)
|
||||
theConf.guiLang = "en_GB"
|
||||
theConf.guiLocale = "en_GB"
|
||||
return theConf
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ def fncConf(fncPath):
|
||||
theConf = Config()
|
||||
theConf.initConfig(fncPath, fncPath)
|
||||
theConf.setLastPath(fncPath)
|
||||
theConf.guiLang = "en_GB"
|
||||
theConf.guiLocale = "en_GB"
|
||||
return theConf
|
||||
|
||||
|
||||
|
||||
+3
-1
@@ -35,6 +35,7 @@ class MockGuiMain(QObject):
|
||||
self.hasProject = True
|
||||
self.theProject = None
|
||||
self.mainStatus = MockStatusBar()
|
||||
self.projPath = ""
|
||||
|
||||
# Test Variables
|
||||
self.askResponse = True
|
||||
@@ -43,7 +44,7 @@ class MockGuiMain(QObject):
|
||||
|
||||
return
|
||||
|
||||
def releaseNotes(self):
|
||||
def postLaunchTasks(self, cmdOpen):
|
||||
return
|
||||
|
||||
def makeAlert(self, message, level=0, exception=None):
|
||||
@@ -61,6 +62,7 @@ class MockGuiMain(QObject):
|
||||
return
|
||||
|
||||
def openProject(self, projPath):
|
||||
self.projPath = projPath
|
||||
return
|
||||
|
||||
def rebuildIndex(self):
|
||||
|
||||
@@ -1,27 +1,32 @@
|
||||
[Meta]
|
||||
timestamp = 2022-11-10 11:10:10
|
||||
|
||||
[Main]
|
||||
timestamp = 2022-10-26 11:19:49
|
||||
theme = default
|
||||
syntax = default_light
|
||||
guifont =
|
||||
guifontsize = 11
|
||||
lastnotes = 0x0
|
||||
guilang = en_GB
|
||||
font =
|
||||
fontsize = 11
|
||||
localisation = en_GB
|
||||
hidevscroll = False
|
||||
hidehscroll = False
|
||||
lastnotes = 0x0
|
||||
lastpath = /home/vkbo
|
||||
|
||||
[Sizes]
|
||||
geometry = 1200, 650
|
||||
mainwindow = 1200, 650
|
||||
preferences = 700, 615
|
||||
projcols = 200, 60, 140
|
||||
projloadcols = 280, 60, 160
|
||||
mainpane = 300, 800
|
||||
viewpane = 500, 150
|
||||
outlinepane = 500, 150
|
||||
fullscreen = False
|
||||
|
||||
[Project]
|
||||
autosaveproject = 60
|
||||
autosavedoc = 30
|
||||
emphlabels = True
|
||||
backuppath =
|
||||
backuponclose = False
|
||||
askbeforebackup = True
|
||||
|
||||
[Editor]
|
||||
textfont = None
|
||||
@@ -61,12 +66,8 @@ highlightemph = True
|
||||
stopwhenidle = True
|
||||
useridletime = 300
|
||||
|
||||
[Backup]
|
||||
backuppath =
|
||||
backuponclose = False
|
||||
askbeforebackup = True
|
||||
|
||||
[State]
|
||||
fullscreen = False
|
||||
showrefpanel = True
|
||||
viewcomments = True
|
||||
viewsynopsis = True
|
||||
@@ -77,6 +78,3 @@ searchloop = False
|
||||
searchnextfile = False
|
||||
searchmatchcap = False
|
||||
|
||||
[Path]
|
||||
lastpath =
|
||||
|
||||
|
||||
@@ -1,27 +1,32 @@
|
||||
[Meta]
|
||||
timestamp = 2022-11-10 11:10:13
|
||||
|
||||
[Main]
|
||||
timestamp = 2022-10-26 11:19:51
|
||||
theme = default
|
||||
syntax = default_light
|
||||
guifont = Cantarell
|
||||
guifontsize = 12
|
||||
lastnotes = 0x0
|
||||
guilang = en_GB
|
||||
font = Cantarell
|
||||
fontsize = 12
|
||||
localisation = en_GB
|
||||
hidevscroll = True
|
||||
hidehscroll = True
|
||||
lastnotes = 0x0
|
||||
lastpath = /home/vkbo/Code/novelWriter/Source/tests/temp/function
|
||||
|
||||
[Sizes]
|
||||
geometry = 1200, 650
|
||||
mainwindow = 1200, 650
|
||||
preferences = 699, 614
|
||||
projcols = 200, 60, 140
|
||||
projloadcols = 280, 60, 160
|
||||
mainpane = 300, 800
|
||||
viewpane = 500, 150
|
||||
outlinepane = 500, 150
|
||||
fullscreen = False
|
||||
|
||||
[Project]
|
||||
autosaveproject = 40
|
||||
autosavedoc = 20
|
||||
emphlabels = True
|
||||
backuppath = some/dir
|
||||
backuponclose = True
|
||||
askbeforebackup = True
|
||||
|
||||
[Editor]
|
||||
textfont = None
|
||||
@@ -61,12 +66,8 @@ highlightemph = False
|
||||
stopwhenidle = True
|
||||
useridletime = 300
|
||||
|
||||
[Backup]
|
||||
backuppath = some/dir
|
||||
backuponclose = True
|
||||
askbeforebackup = True
|
||||
|
||||
[State]
|
||||
fullscreen = False
|
||||
showrefpanel = True
|
||||
viewcomments = True
|
||||
viewsynopsis = True
|
||||
@@ -77,6 +78,3 @@ searchloop = False
|
||||
searchnextfile = False
|
||||
searchmatchcap = False
|
||||
|
||||
[Path]
|
||||
lastpath =
|
||||
|
||||
|
||||
@@ -166,7 +166,7 @@ def testBaseConfig_Localisation(fncPath, tstPaths):
|
||||
|
||||
i18nDir = fncPath / "i18n"
|
||||
i18nDir.mkdir()
|
||||
tstConf._nwLangPath = i18nDir
|
||||
tstConf._nwLangPath = str(i18nDir)
|
||||
|
||||
copyfile(tstPaths.filesDir / "nw_en_GB.qm", i18nDir / "nw_en_GB.qm")
|
||||
writeFile(i18nDir / "nw_en_GB.ts", "")
|
||||
@@ -254,17 +254,17 @@ def testBaseConfig_SettersGetters(tmpConf):
|
||||
# Window Size
|
||||
tmpConf.guiScale = 1.0
|
||||
tmpConf.setMainWinSize(1205, 655)
|
||||
assert tmpConf._confChanged is False
|
||||
assert tmpConf.mainWinSize == [1200, 650]
|
||||
|
||||
tmpConf.guiScale = 2.0
|
||||
tmpConf.setMainWinSize(70, 70)
|
||||
assert tmpConf.mainWinSize == [70, 70]
|
||||
assert tmpConf._winGeometry == [35, 35]
|
||||
assert tmpConf._mainWinSize == [35, 35]
|
||||
|
||||
tmpConf.guiScale = 1.0
|
||||
tmpConf.setMainWinSize(70, 70)
|
||||
assert tmpConf.mainWinSize == [70, 70]
|
||||
assert tmpConf._winGeometry == [70, 70]
|
||||
assert tmpConf._mainWinSize == [70, 70]
|
||||
|
||||
tmpConf.setMainWinSize(1200, 650)
|
||||
|
||||
@@ -272,12 +272,12 @@ def testBaseConfig_SettersGetters(tmpConf):
|
||||
tmpConf.guiScale = 2.0
|
||||
tmpConf.setPreferencesWinSize(70, 70)
|
||||
assert tmpConf.preferencesWinSize == [70, 70]
|
||||
assert tmpConf._prefGeometry == [35, 35]
|
||||
assert tmpConf._prefsWinSize == [35, 35]
|
||||
|
||||
tmpConf.guiScale = 1.0
|
||||
tmpConf.setPreferencesWinSize(70, 70)
|
||||
assert tmpConf.preferencesWinSize == [70, 70]
|
||||
assert tmpConf._prefGeometry == [70, 70]
|
||||
assert tmpConf._prefsWinSize == [70, 70]
|
||||
|
||||
tmpConf.setPreferencesWinSize(700, 615)
|
||||
|
||||
@@ -285,12 +285,12 @@ def testBaseConfig_SettersGetters(tmpConf):
|
||||
tmpConf.guiScale = 2.0
|
||||
tmpConf.setProjLoadColWidths([10, 20, 30])
|
||||
assert tmpConf.projLoadColWidths == [10, 20, 30]
|
||||
assert tmpConf._projColWidth == [5, 10, 15]
|
||||
assert tmpConf._projLoadCols == [5, 10, 15]
|
||||
|
||||
tmpConf.guiScale = 1.0
|
||||
tmpConf.setProjLoadColWidths([10, 20, 30])
|
||||
assert tmpConf.projLoadColWidths == [10, 20, 30]
|
||||
assert tmpConf._projColWidth == [10, 20, 30]
|
||||
assert tmpConf._projLoadCols == [10, 20, 30]
|
||||
|
||||
tmpConf.setProjLoadColWidths([200, 60, 140])
|
||||
|
||||
@@ -348,24 +348,6 @@ def testBaseConfig_SettersGetters(tmpConf):
|
||||
assert tmpConf.getTextMargin() == 80
|
||||
assert tmpConf.getTabWidth() == 80
|
||||
|
||||
# Flag Setters
|
||||
# ============
|
||||
|
||||
tmpConf.setShowRefPanel(False)
|
||||
assert tmpConf.showRefPanel is False
|
||||
tmpConf.setShowRefPanel(True)
|
||||
assert tmpConf.showRefPanel is True
|
||||
|
||||
tmpConf.setViewComments(False)
|
||||
assert tmpConf.viewComments is False
|
||||
tmpConf.setViewComments(True)
|
||||
assert tmpConf.viewComments is True
|
||||
|
||||
tmpConf.setViewSynopsis(False)
|
||||
assert tmpConf.viewSynopsis is False
|
||||
tmpConf.setViewSynopsis(True)
|
||||
assert tmpConf.viewSynopsis is True
|
||||
|
||||
# END Test testBaseConfig_SettersGetters
|
||||
|
||||
|
||||
|
||||
@@ -138,7 +138,6 @@ def testBaseInit_Options(monkeypatch, tmpPath):
|
||||
nwGUI = novelwriter.main(
|
||||
["--testmode", f"--config={tmpPath}", f"--data={tmpPath}", "sample/"]
|
||||
)
|
||||
assert novelwriter.CONFIG.cmdOpen == "sample/"
|
||||
assert nwGUI.closeMain() == "closeMain"
|
||||
|
||||
# END Test testBaseInit_Options
|
||||
|
||||
@@ -215,8 +215,6 @@ def testDlgPreferences_Main(qtbot, monkeypatch, nwGUI, fncPath, tstPaths):
|
||||
qtbot.mouseClick(nwPrefs.buttonBox.button(QDialogButtonBox.Ok), Qt.LeftButton)
|
||||
nwPrefs._doClose()
|
||||
|
||||
assert theConf._confChanged is True
|
||||
|
||||
assert nwGUI.mainConf.saveConfig()
|
||||
projFile = fncPath / "novelwriter.conf"
|
||||
testFile = tstPaths.outDir / "guiPreferences_novelwriter.conf"
|
||||
|
||||
@@ -21,15 +21,18 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
from tools import C, cmpFiles, buildTestProject, XML_IGNORE, writeFile
|
||||
from shutil import copyfile
|
||||
|
||||
from tools import (
|
||||
C, cmpFiles, buildTestProject, XML_IGNORE, getGuiItem, writeFile
|
||||
)
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtWidgets import QMessageBox, QInputDialog
|
||||
from PyQt5.QtWidgets import QDialog, QMessageBox, QInputDialog
|
||||
|
||||
from novelwriter.enum import nwItemType, nwView, nwWidget
|
||||
from novelwriter.tools import GuiProjectWizard
|
||||
from novelwriter.dialogs import GuiEditLabel
|
||||
from novelwriter.dialogs import GuiEditLabel, GuiAbout, GuiProjectLoad
|
||||
from novelwriter.constants import nwFiles
|
||||
from novelwriter.gui.outline import GuiOutlineView
|
||||
from novelwriter.gui.projtree import GuiProjectTree
|
||||
@@ -62,7 +65,39 @@ def testGuiMain_ProjectBlocker(nwGUI):
|
||||
assert nwGUI.showProjectWordListDialog() is False
|
||||
assert nwGUI.showWritingStatsDialog() is False
|
||||
|
||||
# END Test testGuiMain_NoProject
|
||||
# END Test testGuiMain_ProjectBlocker
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def testGuiMain_Launch(qtbot, monkeypatch, nwGUI, prjLipsum):
|
||||
"""Test the handling of launch tasks.
|
||||
"""
|
||||
monkeypatch.setattr(GuiProjectLoad, "exec_", lambda *a: None)
|
||||
monkeypatch.setattr(GuiProjectLoad, "result", lambda *a: QDialog.Accepted)
|
||||
nwGUI.mainConf.lastNotes = "0x0"
|
||||
|
||||
# Open Lipsum project
|
||||
nwGUI.postLaunchTasks(prjLipsum)
|
||||
nwGUI.closeProject()
|
||||
|
||||
# Check that release notes opened
|
||||
qtbot.waitUntil(lambda: getGuiItem("GuiAbout") is not None, timeout=1000)
|
||||
msgAbout = getGuiItem("GuiAbout")
|
||||
assert isinstance(msgAbout, GuiAbout)
|
||||
assert msgAbout.tabBox.currentWidget() == msgAbout.pageNotes
|
||||
msgAbout.accept()
|
||||
|
||||
# Check that project open dialog launches
|
||||
nwGUI.postLaunchTasks(None)
|
||||
qtbot.waitUntil(lambda: getGuiItem("GuiProjectLoad") is not None, timeout=1000)
|
||||
nwLoad = getGuiItem("GuiProjectLoad")
|
||||
assert isinstance(nwLoad, GuiProjectLoad)
|
||||
nwLoad.show()
|
||||
nwLoad.reject()
|
||||
|
||||
# qtbot.stop()
|
||||
|
||||
# END Test testGuiMain_Launch
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
|
||||
@@ -150,7 +150,10 @@ def testGuiTheme_Theme(qtbot, monkeypatch, nwGUI, fncPath):
|
||||
|
||||
# Check handling of broken theme settings
|
||||
mainConf.guiTheme = "not_a_theme"
|
||||
availThemes = mainTheme._availThemes
|
||||
mainTheme._availThemes = {}
|
||||
assert mainTheme.loadTheme() is False
|
||||
mainTheme._availThemes = availThemes
|
||||
|
||||
# Check handling of unreadable file
|
||||
mainConf.guiTheme = "default"
|
||||
@@ -216,8 +219,11 @@ def testGuiTheme_Syntax(qtbot, monkeypatch, nwGUI, fncPath):
|
||||
assert mainTheme.listSyntax() == mainTheme._syntaxList
|
||||
|
||||
# Check handling of broken theme settings
|
||||
availSyntax = mainTheme._availSyntax
|
||||
mainTheme._availSyntax = {}
|
||||
mainConf.guiSyntax = "not_a_syntax"
|
||||
assert mainTheme.loadSyntax() is False
|
||||
mainTheme._availSyntax = availSyntax
|
||||
|
||||
# Check handling of unreadable file
|
||||
mainConf.guiSyntax = "default_light"
|
||||
|
||||
Reference in New Issue
Block a user