+39
-31
@@ -43,13 +43,14 @@ class Config:
|
||||
self.appPath = None
|
||||
self.appRoot = None
|
||||
self.guiPath = None
|
||||
self.themeRoot = None
|
||||
self.themePath = None
|
||||
|
||||
# Set default values
|
||||
self.confChanged = False
|
||||
|
||||
## General
|
||||
self.guiTheme = "default"
|
||||
self.guiTheme = "default_dark"
|
||||
self.winGeometry = [1100, 650]
|
||||
self.treeColWidth = [120, 30, 50]
|
||||
self.mainPanePos = [300, 800]
|
||||
@@ -63,10 +64,11 @@ class Config:
|
||||
self.autoSaveDoc = 30
|
||||
|
||||
## Text Editor
|
||||
self.textFont = None
|
||||
self.textSize = 12
|
||||
self.textFixedW = True
|
||||
self.textWidth = 600
|
||||
self.textMargin = [40, 40]
|
||||
self.textSize = 13
|
||||
self.tabWidth = 40
|
||||
self.doJustify = True
|
||||
self.autoSelect = True
|
||||
@@ -77,9 +79,8 @@ class Config:
|
||||
self.doReplaceDots = True
|
||||
self.wordCountTimer = 5.0
|
||||
|
||||
self.fmtDoubleQuotes = ["“","”"]
|
||||
self.fmtSingleQuotes = ["‘","’"]
|
||||
self.fmtApostrophe = "’"
|
||||
self.fmtDoubleQuotes = ["“","”"]
|
||||
|
||||
self.spellLanguage = "en_GB"
|
||||
|
||||
@@ -106,7 +107,8 @@ class Config:
|
||||
self.appRoot = path.join(self.appPath,path.pardir)
|
||||
self.helpPath = path.join(self.appRoot,"help","en_GB")
|
||||
self.guiPath = path.join(self.appPath,"gui")
|
||||
self.themePath = path.join(self.appPath,"themes")
|
||||
self.themeRoot = path.join(self.appPath,"themes")
|
||||
self.themePath = path.join(self.themeRoot)
|
||||
|
||||
# If config folder does not exist, make it.
|
||||
# This assumes that the os config folder itself exists.
|
||||
@@ -153,19 +155,22 @@ class Config:
|
||||
|
||||
## Editor
|
||||
cnfSec = "Editor"
|
||||
self.textFixedW = self._parseLine(cnfParse, cnfSec, "fixedwidth", self.CNF_BOOL, self.textFixedW)
|
||||
self.textWidth = self._parseLine(cnfParse, cnfSec, "width", self.CNF_INT, self.textWidth)
|
||||
self.textMargin = self._parseLine(cnfParse, cnfSec, "margins", self.CNF_LIST, self.textMargin)
|
||||
self.textSize = self._parseLine(cnfParse, cnfSec, "textsize", self.CNF_INT, self.textSize)
|
||||
self.tabWidth = self._parseLine(cnfParse, cnfSec, "tabwidth", self.CNF_INT, self.tabWidth)
|
||||
self.doJustify = self._parseLine(cnfParse, cnfSec, "justify", self.CNF_BOOL, self.doJustify)
|
||||
self.autoSelect = self._parseLine(cnfParse, cnfSec, "autoselect", self.CNF_BOOL, self.autoSelect)
|
||||
self.doReplace = self._parseLine(cnfParse, cnfSec, "autoreplace", self.CNF_BOOL, self.doReplace)
|
||||
self.doReplaceSQuote = self._parseLine(cnfParse, cnfSec, "repsquotes", self.CNF_BOOL, self.doReplaceSQuote)
|
||||
self.doReplaceDQuote = self._parseLine(cnfParse, cnfSec, "repdquotes", self.CNF_BOOL, self.doReplaceDQuote)
|
||||
self.doReplaceDash = self._parseLine(cnfParse, cnfSec, "repdash", self.CNF_BOOL, self.doReplaceDash)
|
||||
self.doReplaceDots = self._parseLine(cnfParse, cnfSec, "repdots", self.CNF_BOOL, self.doReplaceDots)
|
||||
self.spellLanguage = self._parseLine(cnfParse, cnfSec, "spellcheck", self.CNF_STR, self.spellLanguage)
|
||||
self.textFont = self._parseLine(cnfParse, cnfSec, "textfont", self.CNF_STR, self.textFont)
|
||||
self.textSize = self._parseLine(cnfParse, cnfSec, "textsize", self.CNF_INT, self.textSize)
|
||||
self.textFixedW = self._parseLine(cnfParse, cnfSec, "fixedwidth", self.CNF_BOOL, self.textFixedW)
|
||||
self.textWidth = self._parseLine(cnfParse, cnfSec, "width", self.CNF_INT, self.textWidth)
|
||||
self.textMargin = self._parseLine(cnfParse, cnfSec, "margins", self.CNF_LIST, self.textMargin)
|
||||
self.tabWidth = self._parseLine(cnfParse, cnfSec, "tabwidth", self.CNF_INT, self.tabWidth)
|
||||
self.doJustify = self._parseLine(cnfParse, cnfSec, "justify", self.CNF_BOOL, self.doJustify)
|
||||
self.autoSelect = self._parseLine(cnfParse, cnfSec, "autoselect", self.CNF_BOOL, self.autoSelect)
|
||||
self.doReplace = self._parseLine(cnfParse, cnfSec, "autoreplace", self.CNF_BOOL, self.doReplace)
|
||||
self.doReplaceSQuote = self._parseLine(cnfParse, cnfSec, "repsquotes", self.CNF_BOOL, self.doReplaceSQuote)
|
||||
self.doReplaceDQuote = self._parseLine(cnfParse, cnfSec, "repdquotes", self.CNF_BOOL, self.doReplaceDQuote)
|
||||
self.doReplaceDash = self._parseLine(cnfParse, cnfSec, "repdash", self.CNF_BOOL, self.doReplaceDash)
|
||||
self.doReplaceDots = self._parseLine(cnfParse, cnfSec, "repdots", self.CNF_BOOL, self.doReplaceDots)
|
||||
self.fmtSingleQuotes = self._parseLine(cnfParse, cnfSec, "fmtsinglequote", self.CNF_LIST, self.fmtSingleQuotes)
|
||||
self.fmtDoubleQuotes = self._parseLine(cnfParse, cnfSec, "fmtdoublequote", self.CNF_LIST, self.fmtDoubleQuotes)
|
||||
self.spellLanguage = self._parseLine(cnfParse, cnfSec, "spellcheck", self.CNF_STR, self.spellLanguage)
|
||||
|
||||
## Path
|
||||
cnfSec = "Path"
|
||||
@@ -205,19 +210,22 @@ class Config:
|
||||
## Editor
|
||||
cnfSec = "Editor"
|
||||
cnfParse.add_section(cnfSec)
|
||||
cnfParse.set(cnfSec,"fixedwidth", str(self.textFixedW))
|
||||
cnfParse.set(cnfSec,"width", str(self.textWidth))
|
||||
cnfParse.set(cnfSec,"margins", self._packList(self.textMargin))
|
||||
cnfParse.set(cnfSec,"textsize", str(self.textSize))
|
||||
cnfParse.set(cnfSec,"tabwidth", str(self.tabWidth))
|
||||
cnfParse.set(cnfSec,"justify", str(self.doJustify))
|
||||
cnfParse.set(cnfSec,"autoselect", str(self.autoSelect))
|
||||
cnfParse.set(cnfSec,"autoreplace",str(self.doReplace))
|
||||
cnfParse.set(cnfSec,"repsquotes", str(self.doReplaceSQuote))
|
||||
cnfParse.set(cnfSec,"repdquotes", str(self.doReplaceDQuote))
|
||||
cnfParse.set(cnfSec,"repdash", str(self.doReplaceDash))
|
||||
cnfParse.set(cnfSec,"repdots", str(self.doReplaceDots))
|
||||
cnfParse.set(cnfSec,"spellcheck", str(self.spellLanguage))
|
||||
cnfParse.set(cnfSec,"textfont", str(self.textFont))
|
||||
cnfParse.set(cnfSec,"textsize", str(self.textSize))
|
||||
cnfParse.set(cnfSec,"fixedwidth", str(self.textFixedW))
|
||||
cnfParse.set(cnfSec,"width", str(self.textWidth))
|
||||
cnfParse.set(cnfSec,"margins", self._packList(self.textMargin))
|
||||
cnfParse.set(cnfSec,"tabwidth", str(self.tabWidth))
|
||||
cnfParse.set(cnfSec,"justify", str(self.doJustify))
|
||||
cnfParse.set(cnfSec,"autoselect", str(self.autoSelect))
|
||||
cnfParse.set(cnfSec,"autoreplace", str(self.doReplace))
|
||||
cnfParse.set(cnfSec,"repsquotes", str(self.doReplaceSQuote))
|
||||
cnfParse.set(cnfSec,"repdquotes", str(self.doReplaceDQuote))
|
||||
cnfParse.set(cnfSec,"repdash", str(self.doReplaceDash))
|
||||
cnfParse.set(cnfSec,"repdots", str(self.doReplaceDots))
|
||||
cnfParse.set(cnfSec,"fmtsinglequote",self._packList(self.fmtSingleQuotes))
|
||||
cnfParse.set(cnfSec,"fmtdoublequote",self._packList(self.fmtDoubleQuotes))
|
||||
cnfParse.set(cnfSec,"spellcheck", str(self.spellLanguage))
|
||||
|
||||
## Path
|
||||
cnfSec = "Path"
|
||||
|
||||
@@ -70,3 +70,53 @@ class nwLabels():
|
||||
}
|
||||
|
||||
# END Class nwLabels
|
||||
|
||||
class nwQuotes():
|
||||
"""Allowed quotation marks.
|
||||
Source: https://en.wikipedia.org/wiki/Quotation_mark
|
||||
"""
|
||||
|
||||
SYMBOLS = [
|
||||
"\u0022", # Quotation mark
|
||||
"\u0027", # Apostrophe
|
||||
"\u00ab", # Left-pointing double angle quotation mark
|
||||
"\u00bb", # Right-pointing double angle quotation mark
|
||||
"\u2018", # Left single quotation mark
|
||||
"\u2019", # Right single quotation mark
|
||||
"\u201a", # Single low-9 quotation mark
|
||||
"\u201b", # Single high-reversed-9 quotation mark
|
||||
"\u201c", # Left double quotation mark
|
||||
"\u201d", # Right double quotation mark
|
||||
"\u201e", # Double low-9 quotation mark
|
||||
"\u201f", # Double high-reversed-9 quotation mark
|
||||
"\u2039", # Single left-pointing angle quotation mark
|
||||
"\u203a", # Single right-pointing angle quotation mark
|
||||
"\u2e42", # Double low-reversed-9 quotation mark
|
||||
"\u300c", # Left corner bracket
|
||||
"\u300d", # Right corner bracket
|
||||
"\u300e", # Left white corner bracket
|
||||
"\u300f", # Right white corner bracket
|
||||
]
|
||||
HTML = {
|
||||
"\u0022" : """,
|
||||
"\u0027" : "'",
|
||||
"\u00ab" : "«",
|
||||
"\u00bb" : "»",
|
||||
"\u2018" : "‘",
|
||||
"\u2019" : "’",
|
||||
"\u201a" : "‚",
|
||||
"\u201b" : "‛",
|
||||
"\u201c" : "“",
|
||||
"\u201d" : "”",
|
||||
"\u201e" : "„",
|
||||
"\u201f" : "‟",
|
||||
"\u2039" : "‹",
|
||||
"\u203a" : "›",
|
||||
"\u2e42" : "⹂",
|
||||
"\u300c" : "「",
|
||||
"\u300d" : "」",
|
||||
"\u300e" : "『",
|
||||
"\u300f" : "』",
|
||||
}
|
||||
|
||||
# END Class nwQuotes
|
||||
@@ -0,0 +1,492 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""novelWriter GUI Config Editor
|
||||
|
||||
novelWriter – GUI Config Editor
|
||||
=================================
|
||||
Class holding the config dialog
|
||||
|
||||
File History:
|
||||
Created: 2019-06-10 [0.1.5]
|
||||
|
||||
"""
|
||||
|
||||
import logging
|
||||
import enchant
|
||||
import nw
|
||||
|
||||
from os import path
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QIcon, QPixmap, QColor, QBrush, QStandardItemModel, QFont
|
||||
from PyQt5.QtSvg import QSvgWidget
|
||||
from PyQt5.QtWidgets import (
|
||||
QDialog, QHBoxLayout, QVBoxLayout, QFormLayout, QLineEdit, QPlainTextEdit, QLabel,
|
||||
QWidget, QTabWidget, QDialogButtonBox, QSpinBox, QGroupBox, QComboBox, QMessageBox,
|
||||
QCheckBox, QGridLayout, QFontComboBox
|
||||
)
|
||||
from nw.enum import nwAlert
|
||||
from nw.constants import nwQuotes
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class GuiConfigEditor(QDialog):
|
||||
|
||||
def __init__(self, theParent, theProject):
|
||||
QDialog.__init__(self, theParent)
|
||||
|
||||
logger.debug("Initialising ConfigEditor ...")
|
||||
|
||||
self.mainConf = nw.CONFIG
|
||||
self.theParent = theParent
|
||||
self.theProject = theProject
|
||||
self.outerBox = QHBoxLayout()
|
||||
self.innerBox = QVBoxLayout()
|
||||
|
||||
self.setWindowTitle("Preferences")
|
||||
|
||||
self.gradPath = path.abspath(path.join(self.mainConf.appPath,"graphics","block.svg"))
|
||||
self.svgGradient = QSvgWidget(self.gradPath)
|
||||
self.svgGradient.setFixedWidth(80)
|
||||
|
||||
self.theProject.countStatus()
|
||||
self.tabMain = GuiConfigEditGeneral(self.theParent)
|
||||
self.tabEditor = GuiConfigEditEditor(self.theParent)
|
||||
|
||||
self.tabWidget = QTabWidget()
|
||||
self.tabWidget.addTab(self.tabMain, "General")
|
||||
self.tabWidget.addTab(self.tabEditor, "Editor")
|
||||
|
||||
self.setLayout(self.outerBox)
|
||||
self.outerBox.addWidget(self.svgGradient)
|
||||
self.outerBox.addLayout(self.innerBox)
|
||||
|
||||
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
||||
self.buttonBox.accepted.connect(self._doSave)
|
||||
self.buttonBox.rejected.connect(self._doClose)
|
||||
|
||||
self.innerBox.addWidget(self.tabWidget)
|
||||
self.innerBox.addWidget(self.buttonBox)
|
||||
|
||||
self.show()
|
||||
|
||||
logger.debug("ProjectEditor ConfigEditor complete")
|
||||
|
||||
return
|
||||
|
||||
def _doSave(self):
|
||||
|
||||
logger.verbose("ConfigEditor save button clicked")
|
||||
|
||||
validEntries = True
|
||||
needsRestart = False
|
||||
|
||||
retA, retB = self.tabMain.saveValues()
|
||||
validEntries &= retA
|
||||
needsRestart |= retB
|
||||
|
||||
retA, retB = self.tabEditor.saveValues()
|
||||
validEntries &= retA
|
||||
needsRestart |= retB
|
||||
|
||||
if needsRestart:
|
||||
msgBox = QMessageBox()
|
||||
msgBox.information(
|
||||
self, "Preferences",
|
||||
"Some changes will not be applied until<br>%s has been restarted." % nw.__package__
|
||||
)
|
||||
|
||||
if validEntries:
|
||||
self.accept()
|
||||
|
||||
return
|
||||
|
||||
def _doClose(self):
|
||||
logger.verbose("ConfigEditor close button clicked")
|
||||
self.close()
|
||||
return
|
||||
|
||||
# END Class GuiConfigEditor
|
||||
|
||||
class GuiConfigEditGeneral(QWidget):
|
||||
|
||||
def __init__(self, theParent):
|
||||
QWidget.__init__(self, theParent)
|
||||
|
||||
self.mainConf = nw.CONFIG
|
||||
self.theParent = theParent
|
||||
self.outerBox = QGridLayout()
|
||||
|
||||
# User Interface
|
||||
self.guiLook = QGroupBox("User Interface", self)
|
||||
self.guiLookForm = QGridLayout(self)
|
||||
self.guiLook.setLayout(self.guiLookForm)
|
||||
|
||||
self.guiLookTheme = QComboBox()
|
||||
self.guiLookTheme.setMinimumWidth(200)
|
||||
self.theThemes = self.theParent.theTheme.listThemes()
|
||||
for themeDir, themeName in self.theThemes:
|
||||
self.guiLookTheme.addItem(themeName, themeDir)
|
||||
themeIdx = self.guiLookTheme.findData(self.mainConf.guiTheme)
|
||||
if themeIdx != -1:
|
||||
self.guiLookTheme.setCurrentIndex(themeIdx)
|
||||
|
||||
self.guiLookForm.addWidget(QLabel("Theme"), 0, 0)
|
||||
self.guiLookForm.addWidget(self.guiLookTheme, 0, 1)
|
||||
|
||||
# Spell Checking
|
||||
self.spellLang = QGroupBox("Spell Checker", self)
|
||||
self.spellLangForm = QGridLayout(self)
|
||||
self.spellLang.setLayout(self.spellLangForm)
|
||||
|
||||
self.spellLangList = QComboBox(self)
|
||||
for spTag, spProvider in enchant.list_dicts():
|
||||
self.spellLangList.addItem("%s [%s]" % (spTag, spProvider.name), spTag)
|
||||
spellIdx = self.spellLangList.findData(self.mainConf.spellLanguage)
|
||||
if spellIdx != -1:
|
||||
self.spellLangList.setCurrentIndex(spellIdx)
|
||||
|
||||
self.spellLangForm.addWidget(QLabel("Language"), 0, 0)
|
||||
self.spellLangForm.addWidget(self.spellLangList, 0, 1)
|
||||
self.spellLangForm.setColumnStretch(1, 1)
|
||||
|
||||
# AutoSave
|
||||
self.autoSave = QGroupBox("Auto-Save", self)
|
||||
self.autoSaveForm = QGridLayout(self)
|
||||
self.autoSave.setLayout(self.autoSaveForm)
|
||||
|
||||
self.autoSaveDoc = QSpinBox(self)
|
||||
self.autoSaveDoc.setMinimum(5)
|
||||
self.autoSaveDoc.setMaximum(600)
|
||||
self.autoSaveDoc.setSingleStep(1)
|
||||
self.autoSaveDoc.setValue(self.mainConf.autoSaveDoc)
|
||||
|
||||
self.autoSaveProj = QSpinBox(self)
|
||||
self.autoSaveProj.setMinimum(5)
|
||||
self.autoSaveProj.setMaximum(600)
|
||||
self.autoSaveProj.setSingleStep(1)
|
||||
self.autoSaveProj.setValue(self.mainConf.autoSaveProj)
|
||||
|
||||
self.autoSaveForm.addWidget(QLabel("Document"), 0, 0)
|
||||
self.autoSaveForm.addWidget(self.autoSaveDoc, 0, 1)
|
||||
self.autoSaveForm.addWidget(QLabel("seconds"), 0, 2)
|
||||
self.autoSaveForm.addWidget(QLabel("Project"), 1, 0)
|
||||
self.autoSaveForm.addWidget(self.autoSaveProj, 1, 1)
|
||||
self.autoSaveForm.addWidget(QLabel("seconds"), 1, 2)
|
||||
|
||||
# Assemble
|
||||
self.outerBox.addWidget(self.guiLook, 0, 0)
|
||||
self.outerBox.addWidget(self.spellLang, 1, 0)
|
||||
self.outerBox.addWidget(self.autoSave, 2, 0)
|
||||
self.outerBox.setColumnStretch(2, 1)
|
||||
self.outerBox.setRowStretch(3, 1)
|
||||
self.setLayout(self.outerBox)
|
||||
|
||||
return
|
||||
|
||||
def saveValues(self):
|
||||
|
||||
validEntries = True
|
||||
needsRestart = False
|
||||
|
||||
guiTheme = self.guiLookTheme.currentData()
|
||||
spellLanguage = self.spellLangList.currentData()
|
||||
autoSaveDoc = self.autoSaveDoc.value()
|
||||
autoSaveProj = self.autoSaveProj.value()
|
||||
|
||||
# Check if restart is needed
|
||||
needsRestart |= self.mainConf.guiTheme != guiTheme
|
||||
|
||||
self.mainConf.guiTheme = guiTheme
|
||||
self.mainConf.spellLanguage = spellLanguage
|
||||
self.mainConf.autoSaveDoc = autoSaveDoc
|
||||
self.mainConf.autoSaveProj = autoSaveProj
|
||||
|
||||
self.mainConf.confChanged = True
|
||||
|
||||
return validEntries, needsRestart
|
||||
|
||||
# END Class GuiConfigEditGeneral
|
||||
|
||||
class GuiConfigEditEditor(QWidget):
|
||||
|
||||
def __init__(self, theParent):
|
||||
QWidget.__init__(self, theParent)
|
||||
|
||||
self.mainConf = nw.CONFIG
|
||||
self.theParent = theParent
|
||||
self.outerBox = QGridLayout()
|
||||
|
||||
# Text Style
|
||||
self.textStyle = QGroupBox("Text Style", self)
|
||||
self.textStyleForm = QGridLayout(self)
|
||||
self.textStyle.setLayout(self.textStyleForm)
|
||||
|
||||
self.textStyleFont = QFontComboBox()
|
||||
self.textStyleFont.setMaximumWidth(250)
|
||||
self.textStyleFont.setCurrentFont(QFont(self.mainConf.textFont))
|
||||
|
||||
self.textStyleSize = QSpinBox(self)
|
||||
self.textStyleSize.setMinimum(5)
|
||||
self.textStyleSize.setMaximum(120)
|
||||
self.textStyleSize.setSingleStep(1)
|
||||
self.textStyleSize.setValue(self.mainConf.textSize)
|
||||
|
||||
self.textStyleForm.addWidget(QLabel("Font Family"), 0, 0)
|
||||
self.textStyleForm.addWidget(self.textStyleFont, 0, 1)
|
||||
self.textStyleForm.addWidget(QLabel("Size"), 0, 2)
|
||||
self.textStyleForm.addWidget(self.textStyleSize, 0, 3)
|
||||
self.textStyleForm.setColumnStretch(4, 1)
|
||||
|
||||
# Text Flow
|
||||
self.textFlow = QGroupBox("Text Flow", self)
|
||||
self.textFlowForm = QGridLayout(self)
|
||||
self.textFlow.setLayout(self.textFlowForm)
|
||||
|
||||
self.textFlowFixed = QCheckBox(self)
|
||||
self.textFlowFixed.setToolTip("Make text in editor fixed width and scale margins instead.")
|
||||
if self.mainConf.textFixedW:
|
||||
self.textFlowFixed.setCheckState(Qt.Checked)
|
||||
else:
|
||||
self.textFlowFixed.setCheckState(Qt.Unchecked)
|
||||
self.textFlowWidth = QSpinBox(self)
|
||||
self.textFlowWidth.setMinimum(300)
|
||||
self.textFlowWidth.setMaximum(10000)
|
||||
self.textFlowWidth.setSingleStep(10)
|
||||
self.textFlowWidth.setValue(self.mainConf.textWidth)
|
||||
|
||||
self.textFlowJustify = QCheckBox(self)
|
||||
self.textFlowJustify.setToolTip("Justify text in main document editor.")
|
||||
if self.mainConf.doJustify:
|
||||
self.textFlowJustify.setCheckState(Qt.Checked)
|
||||
else:
|
||||
self.textFlowJustify.setCheckState(Qt.Unchecked)
|
||||
|
||||
self.testFlowAutoSelect = QCheckBox(self)
|
||||
self.testFlowAutoSelect.setToolTip("Auto-select word under cursor when applying formatting.")
|
||||
if self.mainConf.autoSelect:
|
||||
self.testFlowAutoSelect.setCheckState(Qt.Checked)
|
||||
else:
|
||||
self.testFlowAutoSelect.setCheckState(Qt.Unchecked)
|
||||
|
||||
self.textFlowForm.addWidget(QLabel("Fixed Width"), 0, 0)
|
||||
self.textFlowForm.addWidget(self.textFlowFixed, 0, 1)
|
||||
self.textFlowForm.addWidget(self.textFlowWidth, 0, 2)
|
||||
self.textFlowForm.addWidget(QLabel("px"), 0, 3)
|
||||
self.textFlowForm.addWidget(QLabel("Justify Text"), 1, 0)
|
||||
self.textFlowForm.addWidget(self.textFlowJustify, 1, 1)
|
||||
self.textFlowForm.addWidget(QLabel("Auto-Select Text"), 2, 0)
|
||||
self.textFlowForm.addWidget(self.testFlowAutoSelect, 2, 1)
|
||||
self.textFlowForm.setColumnStretch(4, 1)
|
||||
|
||||
# Text Margins
|
||||
self.textMargin = QGroupBox("Margins", self)
|
||||
self.textMarginForm = QGridLayout(self)
|
||||
self.textMargin.setLayout(self.textMarginForm)
|
||||
|
||||
self.textMarginHor = QSpinBox(self)
|
||||
self.textMarginHor.setMinimum(0)
|
||||
self.textMarginHor.setMaximum(2000)
|
||||
self.textMarginHor.setSingleStep(1)
|
||||
self.textMarginHor.setValue(self.mainConf.textMargin[0])
|
||||
|
||||
self.textMarginVer = QSpinBox(self)
|
||||
self.textMarginVer.setMinimum(0)
|
||||
self.textMarginVer.setMaximum(2000)
|
||||
self.textMarginVer.setSingleStep(1)
|
||||
self.textMarginVer.setValue(self.mainConf.textMargin[1])
|
||||
|
||||
self.textMarginTab = QSpinBox(self)
|
||||
self.textMarginTab.setMinimum(0)
|
||||
self.textMarginTab.setMaximum(200)
|
||||
self.textMarginTab.setSingleStep(1)
|
||||
self.textMarginTab.setValue(self.mainConf.tabWidth)
|
||||
|
||||
self.textMarginForm.addWidget(QLabel("Horizontal"), 0, 0)
|
||||
self.textMarginForm.addWidget(self.textMarginHor, 0, 1)
|
||||
self.textMarginForm.addWidget(QLabel("px"), 0, 2)
|
||||
self.textMarginForm.addWidget(QLabel("Vertical"), 1, 0)
|
||||
self.textMarginForm.addWidget(self.textMarginVer, 1, 1)
|
||||
self.textMarginForm.addWidget(QLabel("px"), 1, 2)
|
||||
self.textMarginForm.addWidget(QLabel("Tab Width"), 2, 0)
|
||||
self.textMarginForm.addWidget(self.textMarginTab, 2, 1)
|
||||
self.textMarginForm.addWidget(QLabel("px"), 2, 2)
|
||||
self.textMarginForm.setColumnStretch(4, 1)
|
||||
|
||||
# Auto-Replace
|
||||
self.autoReplace = QGroupBox("Auto-Replace", self)
|
||||
self.autoReplaceForm = QGridLayout(self)
|
||||
self.autoReplace.setLayout(self.autoReplaceForm)
|
||||
|
||||
self.autoReplaceMain = QCheckBox(self)
|
||||
self.autoReplaceMain.setToolTip("Auto-replace text as you type.")
|
||||
if self.mainConf.doReplace:
|
||||
self.autoReplaceMain.setCheckState(Qt.Checked)
|
||||
else:
|
||||
self.autoReplaceMain.setCheckState(Qt.Unchecked)
|
||||
|
||||
self.autoReplaceSQ = QCheckBox(self)
|
||||
self.autoReplaceSQ.setToolTip("Auto-replace single quotes.")
|
||||
if self.mainConf.doReplaceSQuote:
|
||||
self.autoReplaceSQ.setCheckState(Qt.Checked)
|
||||
else:
|
||||
self.autoReplaceSQ.setCheckState(Qt.Unchecked)
|
||||
|
||||
self.autoReplaceSStyleO = QLineEdit()
|
||||
self.autoReplaceSStyleO.setMaxLength(1)
|
||||
self.autoReplaceSStyleO.setFixedWidth(30)
|
||||
self.autoReplaceSStyleO.setAlignment(Qt.AlignCenter)
|
||||
self.autoReplaceSStyleO.setText(self.mainConf.fmtSingleQuotes[0])
|
||||
|
||||
self.autoReplaceSStyleC = QLineEdit()
|
||||
self.autoReplaceSStyleC.setMaxLength(1)
|
||||
self.autoReplaceSStyleC.setFixedWidth(30)
|
||||
self.autoReplaceSStyleC.setAlignment(Qt.AlignCenter)
|
||||
self.autoReplaceSStyleC.setText(self.mainConf.fmtSingleQuotes[1])
|
||||
|
||||
self.autoReplaceDQ = QCheckBox(self)
|
||||
self.autoReplaceDQ.setToolTip("Auto-replace double quotes.")
|
||||
if self.mainConf.doReplaceDQuote:
|
||||
self.autoReplaceDQ.setCheckState(Qt.Checked)
|
||||
else:
|
||||
self.autoReplaceDQ.setCheckState(Qt.Unchecked)
|
||||
|
||||
self.autoReplaceDStyleO = QLineEdit()
|
||||
self.autoReplaceDStyleO.setMaxLength(1)
|
||||
self.autoReplaceDStyleO.setFixedWidth(30)
|
||||
self.autoReplaceDStyleO.setAlignment(Qt.AlignCenter)
|
||||
self.autoReplaceDStyleO.setText(self.mainConf.fmtDoubleQuotes[0])
|
||||
|
||||
self.autoReplaceDStyleC = QLineEdit()
|
||||
self.autoReplaceDStyleC.setMaxLength(1)
|
||||
self.autoReplaceDStyleC.setFixedWidth(30)
|
||||
self.autoReplaceDStyleC.setAlignment(Qt.AlignCenter)
|
||||
self.autoReplaceDStyleC.setText(self.mainConf.fmtDoubleQuotes[1])
|
||||
|
||||
self.autoReplaceDash = QCheckBox(self)
|
||||
self.autoReplaceDash.setToolTip("Auto-replace double and triple hyphens with short and long dash.")
|
||||
if self.mainConf.doReplaceDash:
|
||||
self.autoReplaceDash.setCheckState(Qt.Checked)
|
||||
else:
|
||||
self.autoReplaceDash.setCheckState(Qt.Unchecked)
|
||||
|
||||
self.autoReplaceDots = QCheckBox(self)
|
||||
self.autoReplaceDots.setToolTip("Auto-replace three dots with ellipsis.")
|
||||
if self.mainConf.doReplaceDots:
|
||||
self.autoReplaceDots.setCheckState(Qt.Checked)
|
||||
else:
|
||||
self.autoReplaceDots.setCheckState(Qt.Unchecked)
|
||||
|
||||
self.autoReplaceForm.addWidget(QLabel("Enable Feature"), 0, 0)
|
||||
self.autoReplaceForm.addWidget(self.autoReplaceMain, 0, 1)
|
||||
self.autoReplaceForm.addWidget(QLabel("Single Quotes"), 1, 0)
|
||||
self.autoReplaceForm.addWidget(self.autoReplaceSQ, 1, 1)
|
||||
self.autoReplaceForm.addWidget(QLabel("Open"), 1, 2)
|
||||
self.autoReplaceForm.addWidget(self.autoReplaceSStyleO, 1, 3)
|
||||
self.autoReplaceForm.addWidget(QLabel("Close"), 1, 4)
|
||||
self.autoReplaceForm.addWidget(self.autoReplaceSStyleC, 1, 5)
|
||||
self.autoReplaceForm.addWidget(QLabel("Double Quotes"), 2, 0)
|
||||
self.autoReplaceForm.addWidget(self.autoReplaceDQ, 2, 1)
|
||||
self.autoReplaceForm.addWidget(QLabel("Open"), 2, 2)
|
||||
self.autoReplaceForm.addWidget(self.autoReplaceDStyleO, 2, 3)
|
||||
self.autoReplaceForm.addWidget(QLabel("Close"), 2, 4)
|
||||
self.autoReplaceForm.addWidget(self.autoReplaceDStyleC, 2, 5)
|
||||
self.autoReplaceForm.addWidget(QLabel("Hyphens with Dash"), 3, 0)
|
||||
self.autoReplaceForm.addWidget(self.autoReplaceDash, 3, 1)
|
||||
self.autoReplaceForm.addWidget(QLabel("Dots with Ellipsis"), 4, 0)
|
||||
self.autoReplaceForm.addWidget(self.autoReplaceDots, 4, 1)
|
||||
self.autoReplaceForm.setColumnStretch(6, 1)
|
||||
|
||||
# Assemble
|
||||
self.outerBox.addWidget(self.textStyle, 0, 0, 1, 2)
|
||||
self.outerBox.addWidget(self.textFlow, 1, 0)
|
||||
self.outerBox.addWidget(self.textMargin, 1, 1)
|
||||
self.outerBox.addWidget(self.autoReplace, 2, 0, 1, 2)
|
||||
self.outerBox.setColumnStretch(2, 1)
|
||||
self.setLayout(self.outerBox)
|
||||
|
||||
return
|
||||
|
||||
def saveValues(self):
|
||||
|
||||
validEntries = True
|
||||
|
||||
textFont = self.textStyleFont.currentFont().family()
|
||||
textSize = self.textStyleSize.value()
|
||||
|
||||
self.mainConf.textFont = textFont
|
||||
self.mainConf.textSize = textSize
|
||||
|
||||
textWidth = self.textFlowWidth.value()
|
||||
textFixedW = self.textFlowFixed.isChecked()
|
||||
doJustify = self.textFlowJustify.isChecked()
|
||||
autoSelect = self.testFlowAutoSelect.isChecked()
|
||||
|
||||
self.mainConf.textWidth = textWidth
|
||||
self.mainConf.textFixedW = textFixedW
|
||||
self.mainConf.doJustify = doJustify
|
||||
self.mainConf.autoSelect = autoSelect
|
||||
|
||||
textMarginH = self.textMarginHor.value()
|
||||
textMarginV = self.textMarginVer.value()
|
||||
tabWidth = self.textMarginTab.value()
|
||||
|
||||
self.mainConf.textMargin[0] = textMarginH
|
||||
self.mainConf.textMargin[1] = textMarginV
|
||||
self.mainConf.tabWidth = tabWidth
|
||||
|
||||
doReplace = self.autoReplaceMain.isChecked()
|
||||
doReplaceSQuote = self.autoReplaceSQ.isChecked()
|
||||
doReplaceDQuote = self.autoReplaceDQ.isChecked()
|
||||
doReplaceDash = self.autoReplaceDash.isChecked()
|
||||
doReplaceDots = self.autoReplaceDash.isChecked()
|
||||
fmtSingleQuotesO = self.autoReplaceSStyleO.text()
|
||||
fmtSingleQuotesC = self.autoReplaceSStyleC.text()
|
||||
fmtDoubleQuotesO = self.autoReplaceDStyleO.text()
|
||||
fmtDoubleQuotesC = self.autoReplaceDStyleC.text()
|
||||
|
||||
self.mainConf.doReplace = doReplace
|
||||
self.mainConf.doReplaceSQuote = doReplaceSQuote
|
||||
self.mainConf.doReplaceDQuote = doReplaceDQuote
|
||||
self.mainConf.doReplaceDash = doReplaceDash
|
||||
self.mainConf.doReplaceDots = doReplaceDots
|
||||
|
||||
if self._checkQuoteSymbol(fmtSingleQuotesO):
|
||||
self.mainConf.fmtSingleQuotes[0] = fmtSingleQuotesO
|
||||
else:
|
||||
self.theParent.makeAlert("Invalid quote symbol: %s" % fmtSingleQuotesO, nwAlert.ERROR)
|
||||
validEntries = False
|
||||
|
||||
if self._checkQuoteSymbol(fmtSingleQuotesC):
|
||||
self.mainConf.fmtSingleQuotes[1] = fmtSingleQuotesC
|
||||
else:
|
||||
self.theParent.makeAlert("Invalid quote symbol: %s" % fmtSingleQuotesC, nwAlert.ERROR)
|
||||
validEntries = False
|
||||
|
||||
if self._checkQuoteSymbol(fmtDoubleQuotesO):
|
||||
self.mainConf.fmtDoubleQuotes[0] = fmtDoubleQuotesO
|
||||
else:
|
||||
self.theParent.makeAlert("Invalid quote symbol: %s" % fmtDoubleQuotesO, nwAlert.ERROR)
|
||||
validEntries = False
|
||||
|
||||
if self._checkQuoteSymbol(fmtDoubleQuotesC):
|
||||
self.mainConf.fmtDoubleQuotes[1] = fmtDoubleQuotesC
|
||||
else:
|
||||
self.theParent.makeAlert("Invalid quote symbol: %s" % fmtDoubleQuotesC, nwAlert.ERROR)
|
||||
validEntries = False
|
||||
|
||||
self.mainConf.confChanged = True
|
||||
|
||||
return validEntries, False
|
||||
|
||||
##
|
||||
# Internal Functions
|
||||
##
|
||||
|
||||
def _checkQuoteSymbol(self, toCheck):
|
||||
if len(toCheck) != 1:
|
||||
return False
|
||||
if toCheck in nwQuotes.SYMBOLS:
|
||||
return True
|
||||
return False
|
||||
|
||||
# END Class GuiConfigEditEditor
|
||||
+25
-2
@@ -18,7 +18,7 @@ from time import time
|
||||
|
||||
from PyQt5.QtCore import Qt, QTimer
|
||||
from PyQt5.QtWidgets import QTextEdit, QAction, QMenu, QShortcut
|
||||
from PyQt5.QtGui import QTextCursor, QTextOption, QIcon, QKeySequence
|
||||
from PyQt5.QtGui import QTextCursor, QTextOption, QIcon, QKeySequence, QFont
|
||||
|
||||
from nw.project.document import NWDoc
|
||||
from nw.gui.dochighlight import GuiDocHighlighter
|
||||
@@ -55,7 +55,6 @@ class GuiDocEditor(QTextEdit):
|
||||
self.typDQClose = self.mainConf.fmtDoubleQuotes[1]
|
||||
self.typSQOpen = self.mainConf.fmtSingleQuotes[0]
|
||||
self.typSQClose = self.mainConf.fmtSingleQuotes[1]
|
||||
self.typApos = self.mainConf.fmtApostrophe
|
||||
|
||||
# Core Elements
|
||||
self.theQDoc = self.document()
|
||||
@@ -113,7 +112,21 @@ class GuiDocEditor(QTextEdit):
|
||||
return True
|
||||
|
||||
def initEditor(self):
|
||||
"""Initialise or re-initialise the editor with the user's settings.
|
||||
This function is both called when the editor is created, and when the user changes the
|
||||
main editor preferences.
|
||||
"""
|
||||
|
||||
# Set Font
|
||||
if self.mainConf.textFont is not None:
|
||||
self.setFontFamily(self.mainConf.textFont)
|
||||
else:
|
||||
# If none is defined, set the default back to config
|
||||
theFont = self.theQDoc.defaultFont().family()
|
||||
self.mainConf.textFont = theFont
|
||||
self.setFontPointSize(self.mainConf.textSize)
|
||||
|
||||
# Set text fixed width, or alternatively, just margins
|
||||
if self.mainConf.textFixedW:
|
||||
self.setLineWrapMode(QTextEdit.FixedPixelWidth)
|
||||
self.setLineWrapColumnOrWidth(self.mainConf.textWidth)
|
||||
@@ -121,12 +134,22 @@ class GuiDocEditor(QTextEdit):
|
||||
mTB = self.mainConf.textMargin[0]
|
||||
mLR = self.mainConf.textMargin[1]
|
||||
self.setViewportMargins(mLR,mTB,mLR,mTB)
|
||||
|
||||
# Also set the document text options for the document text flow
|
||||
theOpt = QTextOption()
|
||||
if self.mainConf.tabWidth is not None:
|
||||
theOpt.setTabStopDistance(self.mainConf.tabWidth)
|
||||
if self.mainConf.doJustify:
|
||||
theOpt.setAlignment(Qt.AlignJustify)
|
||||
self.theQDoc.setDefaultTextOption(theOpt)
|
||||
|
||||
# If we have a document open, we should reload it in case the font changed
|
||||
if self.theHandle is not None:
|
||||
tHandle = self.theHandle
|
||||
self.hLight.initHighlighter()
|
||||
self.clearEditor()
|
||||
self.loadText(tHandle)
|
||||
|
||||
return True
|
||||
|
||||
def loadText(self, tHandle):
|
||||
|
||||
+11
-3
@@ -32,7 +32,9 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
||||
self.theDict = None
|
||||
self.theHandle = None
|
||||
self.spellCheck = False
|
||||
self.spellRx = None
|
||||
self.hRules = []
|
||||
self.hStyles = {}
|
||||
|
||||
self.colHead = QColor(*self.theTheme.colHead)
|
||||
self.colHeadH = QColor(*self.theTheme.colHeadH)
|
||||
@@ -47,6 +49,14 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
||||
self.colTagErr = QColor(*self.theTheme.colTagErr)
|
||||
self.colRepTag = QColor(*self.theTheme.colRepTag)
|
||||
|
||||
self.initHighlighter()
|
||||
|
||||
logger.debug("DocHighlighter initialisation complete")
|
||||
|
||||
return
|
||||
|
||||
def initHighlighter(self):
|
||||
|
||||
self.hStyles = {
|
||||
"header1" : self._makeFormat(self.colHead, "bold",1.8),
|
||||
"header2" : self._makeFormat(self.colHead, "bold",1.6),
|
||||
@@ -160,9 +170,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
||||
self.rules = [(QRegularExpression(a),b) for (a,b) in self.hRules]
|
||||
self.spellRx = QRegularExpression(r"\b[^\s]+\b")
|
||||
|
||||
logger.debug("DocHighlighter initialisation complete")
|
||||
|
||||
return
|
||||
return True
|
||||
|
||||
##
|
||||
# Setters
|
||||
|
||||
+6
-4
@@ -492,10 +492,12 @@ class GuiMainMenu(QMenuBar):
|
||||
menuItem.triggered.connect(self.theParent.rebuildIndex)
|
||||
self.toolsMenu.addAction(menuItem)
|
||||
|
||||
# # Tools > Settings
|
||||
# menuItem = QAction(QIcon.fromTheme("preferences-system"), "Preferences", self)
|
||||
# menuItem.setStatusTip("Preferences")
|
||||
# self.toolsMenu.addAction(menuItem)
|
||||
# Tools > Settings
|
||||
menuItem = QAction(QIcon.fromTheme("preferences-system"), "Preferences", self)
|
||||
menuItem.setStatusTip("Preferences")
|
||||
menuItem.setShortcut("Ctrl+,")
|
||||
menuItem.triggered.connect(self.theParent.editConfigDialog)
|
||||
self.toolsMenu.addAction(menuItem)
|
||||
|
||||
return
|
||||
|
||||
|
||||
+20
-6
@@ -19,7 +19,7 @@ from PyQt5.QtCore import Qt, QTimer
|
||||
from PyQt5.QtGui import QIcon, QPixmap, QColor
|
||||
from PyQt5.QtWidgets import (
|
||||
qApp, QWidget, QMainWindow, QVBoxLayout, QFrame, QSplitter, QFileDialog,
|
||||
QShortcut, QMessageBox, QProgressDialog
|
||||
QShortcut, QMessageBox, QProgressDialog, QDialog
|
||||
)
|
||||
|
||||
from nw.gui.doctree import GuiDocTree
|
||||
@@ -27,6 +27,7 @@ from nw.gui.doceditor import GuiDocEditor
|
||||
from nw.gui.docviewer import GuiDocViewer
|
||||
from nw.gui.docdetails import GuiDocDetails
|
||||
from nw.gui.mainmenu import GuiMainMenu
|
||||
from nw.gui.configeditor import GuiConfigEditor
|
||||
from nw.gui.projecteditor import GuiProjectEditor
|
||||
from nw.gui.itemeditor import GuiItemEditor
|
||||
from nw.gui.statusbar import GuiMainStatus
|
||||
@@ -49,7 +50,7 @@ class GuiMain(QMainWindow):
|
||||
|
||||
logger.debug("Initialising GUI ...")
|
||||
self.mainConf = nw.CONFIG
|
||||
self.theTheme = Theme()
|
||||
self.theTheme = Theme(self)
|
||||
self.theProject = NWProject(self)
|
||||
self.theIndex = NWIndex(self.theProject, self)
|
||||
self.hasProject = False
|
||||
@@ -118,15 +119,11 @@ class GuiMain(QMainWindow):
|
||||
|
||||
# Set Up Autosaving Project Timer
|
||||
self.asProjTimer = QTimer()
|
||||
self.asProjTimer.setInterval(int(self.mainConf.autoSaveProj*1000))
|
||||
self.asProjTimer.timeout.connect(self._autoSaveProject)
|
||||
self.asProjTimer.start()
|
||||
|
||||
# Set Up Autosaving Document Timer
|
||||
self.asDocTimer = QTimer()
|
||||
self.asDocTimer.setInterval(int(self.mainConf.autoSaveDoc*1000))
|
||||
self.asDocTimer.timeout.connect(self._autoSaveDocument)
|
||||
self.asDocTimer.start()
|
||||
|
||||
# Keyboard Shortcuts
|
||||
QShortcut(Qt.Key_Return, self.treeView, context=Qt.WidgetShortcut, activated=self._treeKeyPressReturn)
|
||||
@@ -138,6 +135,10 @@ class GuiMain(QMainWindow):
|
||||
if self.mainConf.showGUI:
|
||||
self.show()
|
||||
|
||||
self.initMain()
|
||||
self.asProjTimer.start()
|
||||
self.asDocTimer.start()
|
||||
|
||||
logger.debug("GUI initialisation complete")
|
||||
|
||||
return
|
||||
@@ -149,6 +150,11 @@ class GuiMain(QMainWindow):
|
||||
self.statusBar.clearStatus()
|
||||
return True
|
||||
|
||||
def initMain(self):
|
||||
self.asProjTimer.setInterval(int(self.mainConf.autoSaveProj*1000))
|
||||
self.asDocTimer.setInterval(int(self.mainConf.autoSaveDoc*1000))
|
||||
return True
|
||||
|
||||
##
|
||||
# Project Actions
|
||||
##
|
||||
@@ -454,6 +460,14 @@ class GuiMain(QMainWindow):
|
||||
return projPath
|
||||
return None
|
||||
|
||||
def editConfigDialog(self):
|
||||
dlgConf = GuiConfigEditor(self, self.theProject)
|
||||
if dlgConf.exec_() == QDialog.Accepted:
|
||||
logger.debug("Applying new preferences")
|
||||
self.initMain()
|
||||
self.docEditor.initEditor()
|
||||
return True
|
||||
|
||||
def editProjectDialog(self):
|
||||
if self.hasProject:
|
||||
dlgProj = GuiProjectEditor(self, self.theProject)
|
||||
|
||||
+12
-8
@@ -373,8 +373,9 @@ class NWProject():
|
||||
return True
|
||||
|
||||
def setSpellCheck(self, theMode):
|
||||
self.spellCheck = theMode
|
||||
self.setProjectChanged(True)
|
||||
if self.spellCheck != theMode:
|
||||
self.spellCheck = theMode
|
||||
self.setProjectChanged(True)
|
||||
return True
|
||||
|
||||
def setTreeOrder(self, newOrder):
|
||||
@@ -385,18 +386,21 @@ class NWProject():
|
||||
return True
|
||||
|
||||
def setLastEdited(self, tHandle):
|
||||
self.lastEdited = tHandle
|
||||
self.setProjectChanged(True)
|
||||
if self.lastEdited != tHandle:
|
||||
self.lastEdited = tHandle
|
||||
self.setProjectChanged(True)
|
||||
return True
|
||||
|
||||
def setLastViewed(self, tHandle):
|
||||
self.lastViewed = tHandle
|
||||
self.setProjectChanged(True)
|
||||
if self.lastViewed != tHandle:
|
||||
self.lastViewed = tHandle
|
||||
self.setProjectChanged(True)
|
||||
return True
|
||||
|
||||
def setProjectWordCount(self, theCount):
|
||||
self.currWCount = theCount
|
||||
self.setProjectChanged(True)
|
||||
if self.currWCount != theCount:
|
||||
self.currWCount = theCount
|
||||
self.setProjectChanged(True)
|
||||
return True
|
||||
|
||||
def getSessionWordCount(self):
|
||||
|
||||
+41
-2
@@ -14,19 +14,30 @@ import logging
|
||||
import configparser
|
||||
import nw
|
||||
|
||||
from os import path
|
||||
from os import path, listdir
|
||||
|
||||
from nw.enum import nwAlert
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class Theme:
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, theParent):
|
||||
|
||||
self.mainConf = nw.CONFIG
|
||||
self.theParent = theParent
|
||||
self.cssName = "styles.css"
|
||||
self.confName = "theme.conf"
|
||||
self.themeList = []
|
||||
|
||||
# Loaded Theme Settings
|
||||
|
||||
## Main
|
||||
self.themeName = "No Name"
|
||||
|
||||
## Syntax
|
||||
self.colText = [0,0,0]
|
||||
self.colLink = [0,0,0]
|
||||
self.colHead = [0,0,0]
|
||||
self.colHeadH = [0,0,0]
|
||||
self.colEmph = [0,0,0]
|
||||
@@ -83,6 +94,11 @@ class Theme:
|
||||
logger.error("Could not load theme config file")
|
||||
return False
|
||||
|
||||
## Main
|
||||
cnfSec = "Main"
|
||||
if confParser.has_section(cnfSec):
|
||||
self.themeName = confParser.get(cnfSec,"name")
|
||||
|
||||
## Syntax
|
||||
cnfSec = "Syntax"
|
||||
if confParser.has_section(cnfSec):
|
||||
@@ -103,6 +119,29 @@ class Theme:
|
||||
|
||||
return True
|
||||
|
||||
def listThemes(self):
|
||||
|
||||
if len(self.themeList) > 0:
|
||||
return self.themeList
|
||||
|
||||
confParser = configparser.ConfigParser()
|
||||
for themeDir in listdir(self.mainConf.themeRoot):
|
||||
themeConf = path.join(self.mainConf.themeRoot, themeDir, self.confName)
|
||||
logger.verbose("Checking theme config for '%s'" % themeDir)
|
||||
try:
|
||||
confParser.read_file(open(themeConf))
|
||||
except Exception as e:
|
||||
self.theParent.makeAlert(["Could not load theme config file",str(e)],nwAlert.ERROR)
|
||||
return []
|
||||
themeName = ""
|
||||
if confParser.has_section("Main"):
|
||||
themeName = confParser.get("Main","name")
|
||||
logger.verbose("Theme name is '%s'" % themeName)
|
||||
if themeName != "":
|
||||
self.themeList.append((themeDir, themeName))
|
||||
|
||||
return self.themeList
|
||||
|
||||
##
|
||||
# Internal Functions
|
||||
##
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* Default Theme: Dark
|
||||
*/
|
||||
|
||||
* {
|
||||
background-color: #999999;
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
[Main]
|
||||
name = Default Dark
|
||||
|
||||
[Syntax]
|
||||
text = 199, 207, 208
|
||||
link = 184, 200, 0
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Default Theme: Light
|
||||
*/
|
||||
|
||||
QTreeView, QHeaderView {
|
||||
font-size: 13px;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
[Main]
|
||||
name = Default Light
|
||||
|
||||
[Syntax]
|
||||
text = 0, 0, 0
|
||||
link = 0, 0, 0
|
||||
headertext = 0, 0, 0
|
||||
headertag = 0, 0, 0
|
||||
emphasis = 0, 0, 0
|
||||
straightquotes = 0, 0, 0
|
||||
doublequotes = 0, 0, 0
|
||||
singlequotes = 0, 0, 0
|
||||
hidden = 50, 50, 50
|
||||
keyword = 0, 0, 0
|
||||
value = 0, 0, 0
|
||||
spellcheckline = 0, 0, 0
|
||||
tagerror = 0, 0, 0
|
||||
replacetag = 0, 0, 0
|
||||
@@ -187,3 +187,26 @@ Start: 2019-06-08 20:30:24 End: 2019-06-08 20:42:10 Words: 9
|
||||
Start: 2019-06-08 20:42:14 End: 2019-06-08 20:42:37 Words: 0
|
||||
Start: 2019-06-08 20:42:41 End: 2019-06-08 20:43:25 Words: 0
|
||||
Start: 2019-06-08 20:43:29 End: 2019-06-08 20:43:42 Words: 0
|
||||
Start: 2019-06-10 13:26:52 End: 2019-06-10 13:30:22 Words: 0
|
||||
Start: 2019-06-10 13:30:28 End: 2019-06-10 13:31:44 Words: 0
|
||||
Start: 2019-06-10 14:17:18 End: 2019-06-10 14:17:48 Words: 0
|
||||
Start: 2019-06-10 14:20:17 End: 2019-06-10 14:21:11 Words: 0
|
||||
Start: 2019-06-10 20:41:35 End: 2019-06-10 20:41:48 Words: 0
|
||||
Start: 2019-06-10 20:42:15 End: 2019-06-10 20:42:27 Words: 0
|
||||
Start: 2019-06-10 20:42:43 End: 2019-06-10 20:42:47 Words: 0
|
||||
Start: 2019-06-10 20:45:02 End: 2019-06-10 20:45:07 Words: 0
|
||||
Start: 2019-06-10 20:45:44 End: 2019-06-10 20:46:03 Words: 0
|
||||
Start: 2019-06-10 20:46:08 End: 2019-06-10 20:47:15 Words: 0
|
||||
Start: 2019-06-10 20:47:24 End: 2019-06-10 20:47:28 Words: 0
|
||||
Start: 2019-06-10 20:47:46 End: 2019-06-10 20:47:59 Words: 0
|
||||
Start: 2019-06-10 20:48:02 End: 2019-06-10 20:48:08 Words: 0
|
||||
Start: 2019-06-10 20:57:47 End: 2019-06-10 20:58:01 Words: 0
|
||||
Start: 2019-06-10 21:29:47 End: 2019-06-10 21:33:22 Words: 0
|
||||
Start: 2019-06-10 21:33:26 End: 2019-06-10 21:34:59 Words: 0
|
||||
Start: 2019-06-10 21:39:54 End: 2019-06-10 21:45:25 Words: 0
|
||||
Start: 2019-06-10 21:45:29 End: 2019-06-10 21:47:40 Words: 0
|
||||
Start: 2019-06-10 21:48:06 End: 2019-06-10 21:48:47 Words: 0
|
||||
Start: 2019-06-10 21:48:51 End: 2019-06-10 21:49:07 Words: 0
|
||||
Start: 2019-06-10 22:17:58 End: 2019-06-10 22:18:44 Words: 0
|
||||
Start: 2019-06-10 22:46:35 End: 2019-06-10 22:49:34 Words: 0
|
||||
Start: 2019-06-11 14:44:55 End: 2019-06-11 14:53:47 Words: 0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<novelWriterXML appVersion="0.1.4" fileVersion="1.0" timeStamp="2019-06-08 20:43:42">
|
||||
<novelWriterXML appVersion="0.1.5" fileVersion="1.0" timeStamp="2019-06-11 14:46:19">
|
||||
<project>
|
||||
<name>Sample Project</name>
|
||||
<title>Sample Project</title>
|
||||
@@ -80,7 +80,7 @@
|
||||
<charCount>736</charCount>
|
||||
<wordCount>137</wordCount>
|
||||
<paraCount>6</paraCount>
|
||||
<cursorPos>725</cursorPos>
|
||||
<cursorPos>738</cursorPos>
|
||||
</item>
|
||||
<item handle="bc0cbd2a407f3" order="2" parent="e7ded148d6e4a">
|
||||
<name>New File</name>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[Main]
|
||||
timestamp = 2019-05-25 23:33:23
|
||||
theme = default
|
||||
timestamp = 2019-06-11 18:39:59
|
||||
theme = default_dark
|
||||
|
||||
[Sizes]
|
||||
geometry = 1100, 650
|
||||
@@ -14,10 +14,11 @@ autosaveproject = 60
|
||||
autosavedoc = 30
|
||||
|
||||
[Editor]
|
||||
textfont = None
|
||||
textsize = 12
|
||||
fixedwidth = True
|
||||
width = 600
|
||||
margins = 40, 40
|
||||
textsize = 13
|
||||
tabwidth = 40
|
||||
justify = True
|
||||
autoselect = True
|
||||
@@ -26,6 +27,8 @@ repsquotes = True
|
||||
repdquotes = True
|
||||
repdash = True
|
||||
repdots = True
|
||||
fmtsinglequote = ‘, ’
|
||||
fmtdoublequote = “, ”
|
||||
spellcheck = en_GB
|
||||
|
||||
[Path]
|
||||
|
||||
Reference in New Issue
Block a user