diff --git a/nw/config.py b/nw/config.py index bb8498b1..50941257 100644 --- a/nw/config.py +++ b/nw/config.py @@ -14,9 +14,11 @@ import logging import configparser import nw -from os import path, mkdir, getcwd -from appdirs import user_config_dir -from datetime import datetime +from os import path, mkdir, getcwd +from appdirs import user_config_dir +from datetime import datetime + +from nw.constants import nwFiles logger = logging.getLogger(__name__) @@ -43,6 +45,7 @@ class Config: self.homePath = None self.appPath = None self.appRoot = None + self.appIcon = None self.guiPath = None self.themeRoot = None self.themePath = None @@ -51,7 +54,8 @@ class Config: self.confChanged = False ## General - self.guiTheme = "default_dark" + self.guiTheme = "default" + self.guiSyntax = "default_light" self.winGeometry = [1100, 650] self.treeColWidth = [120, 30, 50] self.mainPanePos = [300, 800] @@ -110,6 +114,7 @@ class Config: self.guiPath = path.join(self.appPath,"gui") self.themeRoot = path.join(self.appPath,"themes") self.themePath = path.join(self.themeRoot) + self.appIcon = path.join(self.appRoot, nwFiles.APP_ICON) # If config folder does not exist, make it. # This assumes that the os config folder itself exists. @@ -144,7 +149,8 @@ class Config: ## Main cnfSec = "Main" - self.guiTheme = self._parseLine(cnfParse, cnfSec, "theme", self.CNF_STR, self.guiTheme) + self.guiTheme = self._parseLine(cnfParse, cnfSec, "theme", self.CNF_STR, self.guiTheme) + self.guiSyntax = self._parseLine(cnfParse, cnfSec, "syntax", self.CNF_STR, self.guiSyntax) ## Sizes cnfSec = "Sizes" @@ -197,6 +203,7 @@ class Config: cnfParse.add_section(cnfSec) cnfParse.set(cnfSec,"timestamp", datetime.now().strftime("%Y-%m-%d %H:%M:%S")) cnfParse.set(cnfSec,"theme", str(self.guiTheme)) + cnfParse.set(cnfSec,"syntax", str(self.guiSyntax)) ## Sizes cnfSec = "Sizes" diff --git a/nw/graphics/block.svg b/nw/graphics/block.svg deleted file mode 100644 index 6546646c..00000000 --- a/nw/graphics/block.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - - - diff --git a/nw/graphics/gear.svg b/nw/graphics/gear.svg new file mode 100644 index 00000000..b5da5b7a --- /dev/null +++ b/nw/graphics/gear.svg @@ -0,0 +1,48 @@ + +image/svg+xml + + \ No newline at end of file diff --git a/nw/graphics/gradient.svg b/nw/graphics/gradient.svg deleted file mode 100644 index 28f83ef1..00000000 --- a/nw/graphics/gradient.svg +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - image/svg+xml - - - - - - - - - diff --git a/nw/gui/configeditor.py b/nw/gui/configeditor.py index 569a6402..d90424f8 100644 --- a/nw/gui/configeditor.py +++ b/nw/gui/configeditor.py @@ -15,7 +15,7 @@ import nw from os import path -from PyQt5.QtCore import Qt +from PyQt5.QtCore import Qt, QSize from PyQt5.QtGui import QIcon, QPixmap, QColor, QBrush, QStandardItemModel, QFont from PyQt5.QtSvg import QSvgWidget from PyQt5.QtWidgets import ( @@ -43,9 +43,9 @@ class GuiConfigEditor(QDialog): 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.gradPath = path.abspath(path.join(self.mainConf.appPath,"graphics","gear.svg")) + self.svgGradient = QSvgWidget(path.join(self.gradPath)) + self.svgGradient.setFixedSize(QSize(64,64)) self.theProject.countStatus() self.tabMain = GuiConfigEditGeneral(self.theParent) @@ -56,7 +56,7 @@ class GuiConfigEditor(QDialog): self.tabWidget.addTab(self.tabEditor, "Editor") self.setLayout(self.outerBox) - self.outerBox.addWidget(self.svgGradient) + self.outerBox.addWidget(self.svgGradient, 0, Qt.AlignTop) self.outerBox.addLayout(self.innerBox) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) @@ -129,8 +129,19 @@ class GuiConfigEditGeneral(QWidget): if themeIdx != -1: self.guiLookTheme.setCurrentIndex(themeIdx) - self.guiLookForm.addWidget(QLabel("Theme"), 0, 0) - self.guiLookForm.addWidget(self.guiLookTheme, 0, 1) + self.guiLookSyntax = QComboBox() + self.guiLookSyntax.setMinimumWidth(200) + self.theSyntaxes = self.theParent.theTheme.listSyntax() + for syntaxFile, syntaxName in self.theSyntaxes: + self.guiLookSyntax.addItem(syntaxName, syntaxFile) + syntaxIdx = self.guiLookSyntax.findData(self.mainConf.guiSyntax) + if syntaxIdx != -1: + self.guiLookSyntax.setCurrentIndex(syntaxIdx) + + self.guiLookForm.addWidget(QLabel("Theme"), 0, 0) + self.guiLookForm.addWidget(self.guiLookTheme, 0, 1) + self.guiLookForm.addWidget(QLabel("Syntax"), 1, 0) + self.guiLookForm.addWidget(self.guiLookSyntax, 1, 1) # Spell Checking self.spellLang = QGroupBox("Spell Checker", self) @@ -188,6 +199,7 @@ class GuiConfigEditGeneral(QWidget): needsRestart = False guiTheme = self.guiLookTheme.currentData() + guiSyntax = self.guiLookSyntax.currentData() spellLanguage = self.spellLangList.currentData() autoSaveDoc = self.autoSaveDoc.value() autoSaveProj = self.autoSaveProj.value() @@ -196,6 +208,7 @@ class GuiConfigEditGeneral(QWidget): needsRestart |= self.mainConf.guiTheme != guiTheme self.mainConf.guiTheme = guiTheme + self.mainConf.guiSyntax = guiSyntax self.mainConf.spellLanguage = spellLanguage self.mainConf.autoSaveDoc = autoSaveDoc self.mainConf.autoSaveProj = autoSaveProj diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index a4b7d04a..af81f802 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -17,7 +17,7 @@ from time import time from PyQt5.QtCore import Qt, QTimer, QSizeF from PyQt5.QtWidgets import QTextEdit, QAction, QMenu, QShortcut -from PyQt5.QtGui import QTextCursor, QTextOption, QIcon, QKeySequence, QFont +from PyQt5.QtGui import QTextCursor, QTextOption, QIcon, QKeySequence, QFont, QColor, QPalette from nw.project.document import NWDoc from nw.gui.dochighlight import GuiDocHighlighter @@ -37,8 +37,9 @@ class GuiDocEditor(QTextEdit): # Class Variables self.mainConf = nw.CONFIG - self.theParent = theParent self.theProject = theProject + self.theParent = theParent + self.theTheme = theParent.theTheme self.docChanged = False self.spellCheck = False self.nwDocument = NWDoc(self.theProject, self.theParent) @@ -58,6 +59,7 @@ class GuiDocEditor(QTextEdit): # Core Elements self.qDocument = self.document() + self.qDocument.setDocumentMargin(self.mainConf.textMargin) self.qDocument.contentsChange.connect(self._docChange) if self.mainConf.spellTool == "enchant": from nw.tools.spellenchant import NWSpellEnchant @@ -89,7 +91,6 @@ class GuiDocEditor(QTextEdit): self.wCounter = WordCounter(self) self.wCounter.finished.connect(self._updateCounts) - self.clearEditor() self.initEditor() logger.debug("DocEditor initialisation complete") @@ -132,9 +133,13 @@ class GuiDocEditor(QTextEdit): theFont.setPointSize(self.mainConf.textSize) self.setFont(theFont) - # Set text fixed width, or alternatively, just margins + docPalette = self.palette() + docPalette.setColor(QPalette.Base, QColor(*self.theTheme.colBack)) + docPalette.setColor(QPalette.Text, QColor(*self.theTheme.colText)) + self.setPalette(docPalette) + + # Set default text margins self.qDocument.setDocumentMargin(self.mainConf.textMargin) - self.changeWidth() # Also set the document text options for the document text flow theOpt = QTextOption() @@ -144,12 +149,14 @@ class GuiDocEditor(QTextEdit): theOpt.setAlignment(Qt.AlignJustify) self.qDocument.setDefaultTextOption(theOpt) + self.hLight.initHighlighter() + # 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) + self.changeWidth() return True @@ -220,18 +227,14 @@ class GuiDocEditor(QTextEdit): def setSpellCheck(self, theMode): self.spellCheck = theMode self.hLight.setSpellCheck(theMode) - self.rehighlightDocument() + self.hLight.rehighlight() return True def updateSpellCheck(self): if self.spellCheck: - self.rehighlightDocument() + self.hLight.rehighlight() return True - def rehighlightDocument(self): - self.hLight.rehighlight() - return - ## # General Class Methods ## @@ -251,11 +254,11 @@ class GuiDocEditor(QTextEdit): tM = int((wW - sW - tW)/2) if tM < 0: tM = 0 - # print(wW, tW, dW, sW, tM) - self.setViewportMargins(tM,0,tM,0) - self.qDocument.setTextWidth(tW) - else: - self.setViewportMargins(0,0,0,0) + docFormat = self.qDocument.rootFrame().frameFormat() + docFormat.setLeftMargin(tM) + docFormat.setRightMargin(tM) + self.qDocument.rootFrame().setFrameFormat(docFormat) + return def docAction(self, theAction): @@ -359,7 +362,8 @@ class GuiDocEditor(QTextEdit): def _docChange(self, thePos, charsRemoved, charsAdded): self.lastEdit = time() - self.setDocumentChanged(True) + if not self.docChanged: + self.setDocumentChanged(True) if not self.wcTimer.isActive(): self.wcTimer.start() if self.mainConf.doReplace and not self.hasSelection: diff --git a/nw/gui/dochighlight.py b/nw/gui/dochighlight.py index 97fb1e89..f4c8e1f2 100644 --- a/nw/gui/dochighlight.py +++ b/nw/gui/dochighlight.py @@ -36,18 +36,18 @@ class GuiDocHighlighter(QSyntaxHighlighter): self.hRules = [] self.hStyles = {} - self.colHead = QColor(*self.theTheme.colHead) - self.colHeadH = QColor(*self.theTheme.colHeadH) - self.colEmph = QColor(*self.theTheme.colEmph) - self.colDialN = QColor(*self.theTheme.colDialN) - self.colDialD = QColor(*self.theTheme.colDialD) - self.colDialS = QColor(*self.theTheme.colDialS) - self.colComm = QColor(*self.theTheme.colComm) - self.colKey = QColor(*self.theTheme.colKey) - self.colVal = QColor(*self.theTheme.colVal) - self.colSpell = QColor(*self.theTheme.colSpell) - self.colTagErr = QColor(*self.theTheme.colTagErr) - self.colRepTag = QColor(*self.theTheme.colRepTag) + self.colHead = QColor(0,0,0) + self.colHeadH = QColor(0,0,0) + self.colEmph = QColor(0,0,0) + self.colDialN = QColor(0,0,0) + self.colDialD = QColor(0,0,0) + self.colDialS = QColor(0,0,0) + self.colComm = QColor(0,0,0) + self.colKey = QColor(0,0,0) + self.colVal = QColor(0,0,0) + self.colSpell = QColor(0,0,0) + self.colTagErr = QColor(0,0,0) + self.colRepTag = QColor(0,0,0) self.initHighlighter() @@ -57,6 +57,21 @@ class GuiDocHighlighter(QSyntaxHighlighter): def initHighlighter(self): + logger.debug("Setting up highlighting rules") + + self.colHead = QColor(*self.theTheme.colHead) + self.colHeadH = QColor(*self.theTheme.colHeadH) + self.colEmph = QColor(*self.theTheme.colEmph) + self.colDialN = QColor(*self.theTheme.colDialN) + self.colDialD = QColor(*self.theTheme.colDialD) + self.colDialS = QColor(*self.theTheme.colDialS) + self.colComm = QColor(*self.theTheme.colComm) + self.colKey = QColor(*self.theTheme.colKey) + self.colVal = QColor(*self.theTheme.colVal) + self.colSpell = QColor(*self.theTheme.colSpell) + self.colTagErr = QColor(*self.theTheme.colTagErr) + self.colRepTag = QColor(*self.theTheme.colRepTag) + self.hStyles = { "header1" : self._makeFormat(self.colHead, "bold",1.8), "header2" : self._makeFormat(self.colHead, "bold",1.6), @@ -80,6 +95,7 @@ class GuiDocHighlighter(QSyntaxHighlighter): } # Headers + self.hRules = [] self.hRules.append(( r"^(#{1}) (.*)[^\n]", { 0 : self.hStyles["header1"], diff --git a/nw/gui/doctree.py b/nw/gui/doctree.py index 3614306e..07002b2c 100644 --- a/nw/gui/doctree.py +++ b/nw/gui/doctree.py @@ -360,7 +360,7 @@ class GuiDocTree(QTreeWidget): newItem.setText(self.C_FLAGS, "") newItem.setText(self.C_HANDLE, tHandle) - newItem.setForeground(self.C_COUNT,QColor(0,105,135)) + # newItem.setForeground(self.C_COUNT,QColor(*self.theParent.theTheme.treeWCount)) newItem.setTextAlignment(self.C_COUNT,Qt.AlignRight) newItem.setFont(self.C_FLAGS,self.fontFlags) diff --git a/nw/gui/docviewer.py b/nw/gui/docviewer.py index 3ea62455..d2062b87 100644 --- a/nw/gui/docviewer.py +++ b/nw/gui/docviewer.py @@ -15,7 +15,7 @@ import nw from PyQt5.QtCore import Qt, QUrl from PyQt5.QtWidgets import QTextBrowser -from PyQt5.QtGui import QTextOption, QFont +from PyQt5.QtGui import QTextOption, QFont, QPalette, QColor from nw.convert.tokenizer import Tokenizer from nw.convert.tohtml import ToHtml @@ -37,57 +37,14 @@ class GuiDocViewer(QTextBrowser): self.theTheme = theParent.theTheme self.theHandle = None - self.theQDoc = self.document() - self.theQDoc.setDefaultStyleSheet(( - "body {{" - " font-size: {textSize}pt;" - " color: rgb({tColR},{tColG},{tColB});" - "}}\n" - "h1, h2, h3, h4 {{" - " color: rgb({hColR},{hColG},{hColB});" - "}}\n" - "a {{" - " color: rgb({aColR},{aColG},{aColB});" - "}}\n" - "pre {{" - " color: rgb({cColR},{cColG},{cColB});" - " font-size: {preSize}pt;" - "}}\n" - "mark {{" - " color: rgb({eColR},{eColG},{eColB});" - "}}\n" - "table {{" - " margin: 10px 0px;" - "}}\n" - "td {{" - " padding: 0px 4px;" - "}}\n" - ).format( - textSize = self.mainConf.textSize, - preSize = self.mainConf.textSize*0.9, - tColR = self.theTheme.colText[0], - tColG = self.theTheme.colText[1], - tColB = self.theTheme.colText[2], - hColR = self.theTheme.colHead[0], - hColG = self.theTheme.colHead[1], - hColB = self.theTheme.colHead[2], - cColR = self.theTheme.colComm[0], - cColG = self.theTheme.colComm[1], - cColB = self.theTheme.colComm[2], - eColR = self.theTheme.colEmph[0], - eColG = self.theTheme.colEmph[1], - eColB = self.theTheme.colEmph[2], - aColR = self.theTheme.colLink[0], - aColG = self.theTheme.colLink[1], - aColB = self.theTheme.colLink[2], - )) + self.qDocument = self.document() self.setMinimumWidth(300) self.initViewer() theOpt = QTextOption() if self.mainConf.doJustify: theOpt.setAlignment(Qt.AlignJustify) - self.theQDoc.setDefaultTextOption(theOpt) + self.qDocument.setDefaultTextOption(theOpt) logger.debug("DocViewer initialisation complete") @@ -102,20 +59,27 @@ class GuiDocViewer(QTextBrowser): """Set editor settings from main config. """ + self._makeStyleSheet() + # Set Font theFont = QFont() if self.mainConf.textFont is None: # If none is defined, set the default back to config - self.mainConf.textFont = self.theQDoc.defaultFont().family() + self.mainConf.textFont = self.qDocument.defaultFont().family() theFont.setFamily(self.mainConf.textFont) theFont.setPointSize(self.mainConf.textSize) self.setFont(theFont) - self.theQDoc.setDocumentMargin(self.mainConf.textMargin) + docPalette = self.palette() + docPalette.setColor(QPalette.Base, QColor(*self.theTheme.colBack)) + docPalette.setColor(QPalette.Text, QColor(*self.theTheme.colText)) + self.setPalette(docPalette) + + self.qDocument.setDocumentMargin(self.mainConf.textMargin) theOpt = QTextOption() if self.mainConf.doJustify: theOpt.setAlignment(Qt.AlignJustify) - self.theQDoc.setDefaultTextOption(theOpt) + self.qDocument.setDefaultTextOption(theOpt) # If we have a document open, we should reload it in case the font changed if self.theHandle is not None: @@ -162,4 +126,56 @@ class GuiDocViewer(QTextBrowser): return True + ## + # Internal Functions + ## + + def _makeStyleSheet(self): + + self.qDocument.setDefaultStyleSheet(( + "body {{" + " font-size: {textSize}pt;" + " color: rgb({tColR},{tColG},{tColB});" + "}}\n" + "h1, h2, h3, h4 {{" + " color: rgb({hColR},{hColG},{hColB});" + "}}\n" + "a {{" + " color: rgb({aColR},{aColG},{aColB});" + "}}\n" + "pre {{" + " color: rgb({cColR},{cColG},{cColB});" + " font-size: {preSize}pt;" + "}}\n" + "mark {{" + " color: rgb({eColR},{eColG},{eColB});" + "}}\n" + "table {{" + " margin: 10px 0px;" + "}}\n" + "td {{" + " padding: 0px 4px;" + "}}\n" + ).format( + textSize = self.mainConf.textSize, + preSize = self.mainConf.textSize*0.9, + tColR = self.theTheme.colText[0], + tColG = self.theTheme.colText[1], + tColB = self.theTheme.colText[2], + hColR = self.theTheme.colHead[0], + hColG = self.theTheme.colHead[1], + hColB = self.theTheme.colHead[2], + cColR = self.theTheme.colComm[0], + cColG = self.theTheme.colComm[1], + cColB = self.theTheme.colComm[2], + eColR = self.theTheme.colEmph[0], + eColG = self.theTheme.colEmph[1], + eColB = self.theTheme.colEmph[2], + aColR = self.theTheme.colLink[0], + aColG = self.theTheme.colLink[1], + aColB = self.theTheme.colLink[2], + )) + + return True + # END Class GuiDocViewer diff --git a/nw/gui/itemeditor.py b/nw/gui/itemeditor.py index 06edf0fd..a049aaf2 100644 --- a/nw/gui/itemeditor.py +++ b/nw/gui/itemeditor.py @@ -15,6 +15,7 @@ import nw from os import path +from PyQt5.QtCore import Qt, QSize from PyQt5.QtWidgets import QDialog, QHBoxLayout, QVBoxLayout, QGroupBox, QFormLayout, QLineEdit, QPushButton, QComboBox from PyQt5.QtSvg import QSvgWidget @@ -40,11 +41,12 @@ class GuiItemEditor(QDialog): self.setWindowTitle("Item Settings") - self.gradPath = path.abspath(path.join(self.mainConf.appPath,"graphics","block.svg")) + self.gradPath = path.abspath(path.join(self.mainConf.appPath,"graphics","gear.svg")) self.svgGradient = QSvgWidget(self.gradPath) - self.svgGradient.setFixedWidth(80) + self.svgGradient.setFixedSize(QSize(64,64)) + self.setLayout(self.outerBox) - self.outerBox.addWidget(self.svgGradient) + self.outerBox.addWidget(self.svgGradient, 0, Qt.AlignTop) self.outerBox.addLayout(self.innerBox) self.mainGroup = QGroupBox("Item Settings") diff --git a/nw/gui/mainmenu.py b/nw/gui/mainmenu.py index 5c91f71c..917af5f8 100644 --- a/nw/gui/mainmenu.py +++ b/nw/gui/mainmenu.py @@ -104,8 +104,8 @@ class GuiMainMenu(QMenuBar): return True def _showAbout(self): - msgBox = QMessageBox() - msgBox.about(self.theParent, "About %s" % nw.__package__, ( + listPrefix = "  •  " + aboutMsg = ( "

About {name:s}

" "

Version: {version:s}
Release Date: {date:s}

" "

{name:s} is a markdown-like text editor designed for organising and writing novels. " @@ -121,8 +121,23 @@ class GuiMainMenu(QMenuBar): date = nw.__date__, copyright = nw.__copyright__, website = nw.__url__, - credits = "".join(["  •  %s
" % x for x in nw.__credits__]), - )) + credits = "
".join(["%s%s" % (listPrefix, x) for x in nw.__credits__]), + ) + theTheme = self.theParent.theTheme + if theTheme.themeCredit != "" or theTheme.syntaxCredit != "": + aboutMsg += "

GUI Theme and Syntax Highlighting

" + aboutMsg += "

" + if theTheme.themeCredit != "": + aboutMsg += "%s%s by %s
" % ( + listPrefix, theTheme.themeName, theTheme.themeCredit + ) + if theTheme.syntaxCredit != "": + aboutMsg += "%s%s by %s
" % ( + listPrefix, theTheme.syntaxName, theTheme.syntaxCredit + ) + aboutMsg += "

" + msgBox = QMessageBox() + msgBox.about(self.theParent, "About %s" % nw.__package__, aboutMsg) return True def _showAboutQt(self): diff --git a/nw/gui/projecteditor.py b/nw/gui/projecteditor.py index c440dca4..8f5bf681 100644 --- a/nw/gui/projecteditor.py +++ b/nw/gui/projecteditor.py @@ -15,7 +15,7 @@ import nw from os import path -from PyQt5.QtCore import Qt +from PyQt5.QtCore import Qt, QSize from PyQt5.QtGui import QIcon, QPixmap, QColor, QBrush, QStandardItemModel from PyQt5.QtSvg import QSvgWidget from PyQt5.QtWidgets import ( @@ -37,14 +37,15 @@ class GuiProjectEditor(QDialog): self.mainConf = nw.CONFIG self.theParent = theParent self.theProject = theProject + self.outerBox = QHBoxLayout() self.innerBox = QVBoxLayout() - self.setWindowTitle("Project Settings") + self.setLayout(self.outerBox) - self.gradPath = path.abspath(path.join(self.mainConf.appPath,"graphics","block.svg")) + self.gradPath = path.abspath(path.join(self.mainConf.appPath,"graphics","gear.svg")) self.svgGradient = QSvgWidget(self.gradPath) - self.svgGradient.setFixedWidth(80) + self.svgGradient.setFixedSize(QSize(64,64)) self.theProject.countStatus() self.tabMain = GuiProjectEditMain(self.theParent, self.theProject) @@ -58,8 +59,7 @@ class GuiProjectEditor(QDialog): self.tabWidget.addTab(self.tabImport, "Importance") self.tabWidget.addTab(self.tabReplace,"Auto-Replace") - self.setLayout(self.outerBox) - self.outerBox.addWidget(self.svgGradient) + self.outerBox.addWidget(self.svgGradient, 0, Qt.AlignTop) self.outerBox.addLayout(self.innerBox) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) diff --git a/nw/gui/statusbar.py b/nw/gui/statusbar.py index 79952289..d69f50ee 100644 --- a/nw/gui/statusbar.py +++ b/nw/gui/statusbar.py @@ -27,15 +27,17 @@ class GuiMainStatus(QStatusBar): logger.debug("Initialising GuiMainStatus ...") - self.mainConf = nw.CONFIG - self.refTime = None + self.mainConf = nw.CONFIG + self.theParent = theParent + self.refTime = None self.iconGrey = QPixmap(16,16) - self.iconGrey.fill(QColor(120,120,120)) self.iconYellow = QPixmap(16,16) - self.iconYellow.fill(QColor(120,120, 40)) self.iconGreen = QPixmap(16,16) - self.iconGreen.fill(QColor( 40,120, 0)) + + self.iconGrey.fill(QColor(*self.theParent.theTheme.statNone)) + self.iconYellow.fill(QColor(*self.theParent.theTheme.statUnsaved)) + self.iconGreen.fill(QColor(*self.theParent.theTheme.statSaved)) self.boxStats = QLabel() self.boxStats.setToolTip("Project Word Count | Session Word Count") diff --git a/nw/gui/winmain.py b/nw/gui/winmain.py index da2ed168..374668a6 100644 --- a/nw/gui/winmain.py +++ b/nw/gui/winmain.py @@ -48,6 +48,7 @@ class GuiMain(QMainWindow): def __init__(self): QWidget.__init__(self) + logger.info("Starting %s" % nw.__package__) logger.debug("Initialising GUI ...") self.mainConf = nw.CONFIG self.theTheme = Theme(self) @@ -57,8 +58,7 @@ class GuiMain(QMainWindow): self.resize(*self.mainConf.winGeometry) self._setWindowTitle() - self.setWindowIcon(QIcon(path.join(self.mainConf.appRoot, nwFiles.APP_ICON))) - self.theTheme.loadTheme() + self.setWindowIcon(QIcon(path.join(self.mainConf.appIcon))) # Main GUI Elements self.statusBar = GuiMainStatus(self) @@ -114,9 +114,6 @@ class GuiMain(QMainWindow): self.setStatusBar(self.statusBar) self.statusBar.showMessage("Ready") - # Load Theme StyleSheet - self.setStyleSheet(self.theTheme.cssData) - # Set Up Autosaving Project Timer self.asProjTimer = QTimer() self.asProjTimer.timeout.connect(self._autoSaveProject) @@ -138,6 +135,7 @@ class GuiMain(QMainWindow): self.initMain() self.asProjTimer.start() self.asDocTimer.start() + self.statusBar.clearStatus() logger.debug("GUI initialisation complete") @@ -467,6 +465,7 @@ class GuiMain(QMainWindow): if dlgConf.exec_() == QDialog.Accepted: logger.debug("Applying new preferences") self.initMain() + self.theTheme.updateTheme() self.docEditor.initEditor() self.docViewer.initViewer() return True diff --git a/nw/theme.py b/nw/theme.py index f0a8db3c..5b96c59b 100644 --- a/nw/theme.py +++ b/nw/theme.py @@ -16,6 +16,9 @@ import nw from os import path, listdir +from PyQt5.QtWidgets import qApp +from PyQt5.QtGui import QPalette, QColor + from nw.enum import nwAlert logger = logging.getLogger(__name__) @@ -24,39 +27,60 @@ class Theme: def __init__(self, theParent): - self.mainConf = nw.CONFIG - self.theParent = theParent - self.cssName = "styles.css" - self.confName = "theme.conf" - self.themeList = [] + self.mainConf = nw.CONFIG + self.theParent = theParent + self.guiPalette = QPalette() + self.guiPath = "gui" + self.syntaxPath = "syntax" + self.cssName = "style.qss" + self.confName = "theme.conf" + self.themeList = [] + self.syntaxList = [] # Loaded Theme Settings - ## Main - self.themeName = "No Name" + ## Theme + self.themeName = "" + self.themeAuthor = "" + self.themeCredit = "" + self.themeUrl = "" - ## 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] - self.colDialN = [0,0,0] - self.colDialD = [0,0,0] - self.colDialS = [0,0,0] - self.colComm = [0,0,0] - self.colKey = [0,0,0] - self.colVal = [0,0,0] - self.colSpell = [0,0,0] - self.colTagErr = [0,0,0] - self.colRepTag = [0,0,0] + ## GUI + self.treeWCount = [ 0, 0, 0] + self.statNone = [120,120,120] + self.statUnsaved = [120,120, 40] + self.statSaved = [ 40,120, 0] + + # Loaded Syntax Settings + + ## Main + self.syntaxName = "" + self.syntaxAuthor = "" + self.syntaxCredit = "" + self.syntaxUrl = "" + + ## Colours + self.colBack = [255,255,255] + 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] + self.colDialN = [ 0, 0, 0] + self.colDialD = [ 0, 0, 0] + self.colDialS = [ 0, 0, 0] + self.colComm = [ 0, 0, 0] + self.colKey = [ 0, 0, 0] + self.colVal = [ 0, 0, 0] + self.colSpell = [ 0, 0, 0] + self.colTagErr = [ 0, 0, 0] + self.colRepTag = [ 0, 0, 0] # Changeable Settings - self.guiTheme = None - self.themePath = None - self.confFile = None - self.cssFile = None - self.cssData = "" + self.guiTheme = None + self.guiSyntax = None + self.themeRoot = None + self.cssFile = None self.updateTheme() @@ -67,10 +91,18 @@ class Theme: ## def updateTheme(self): - self.guiTheme = self.mainConf.guiTheme - self.themePath = path.join(self.mainConf.themePath, self.guiTheme) - self.confFile = path.join(self.themePath,self.confName) - self.cssFile = path.join(self.themePath,self.cssName) + + self.guiTheme = self.mainConf.guiTheme + self.guiSyntax = self.mainConf.guiSyntax + self.themeRoot = self.mainConf.themeRoot + self.themePath = path.join(self.mainConf.themeRoot, self.guiPath, self.guiTheme) + self.syntaxFile = path.join(self.themeRoot,self.syntaxPath,self.guiSyntax+".conf") + self.confFile = path.join(self.themePath,self.confName) + self.cssFile = path.join(self.themePath,self.cssName) + + self.loadTheme() + self.loadSyntax() + return True def loadTheme(self): @@ -78,30 +110,82 @@ class Theme: logger.debug("Loading theme files") # CSS File + cssData = "" try: if path.isfile(self.cssFile): with open(self.cssFile,mode="r") as inFile: - self.cssData = inFile.read() + cssData = inFile.read() except Exception as e: logger.error("Could not load theme css file") return False - # Color Config + # Config File confParser = configparser.ConfigParser() try: confParser.read_file(open(self.confFile)) except Exception as e: - logger.error("Could not load theme config file") + logger.error("Could not load theme settings from: %s" % self.confFile) return False ## Main cnfSec = "Main" if confParser.has_section(cnfSec): - self.themeName = confParser.get(cnfSec,"name") + self.themeName = self._parseLine(confParser,cnfSec,"name", "") + self.themeAuthor = self._parseLine(confParser,cnfSec,"author","") + self.themeCredit = self._parseLine(confParser,cnfSec,"credit","") + self.themeUrl = self._parseLine(confParser,cnfSec,"url", "") + + ## Palette + cnfSec = "Palette" + if confParser.has_section(cnfSec): + self._setPalette(confParser,cnfSec,"window", QPalette.Window) + self._setPalette(confParser,cnfSec,"windowtext", QPalette.WindowText) + self._setPalette(confParser,cnfSec,"base", QPalette.Base) + self._setPalette(confParser,cnfSec,"alternatebase",QPalette.AlternateBase) + self._setPalette(confParser,cnfSec,"text", QPalette.Text) + self._setPalette(confParser,cnfSec,"tooltipbase", QPalette.ToolTipBase) + self._setPalette(confParser,cnfSec,"tooltiptext", QPalette.ToolTipText) + self._setPalette(confParser,cnfSec,"button", QPalette.Button) + self._setPalette(confParser,cnfSec,"buttontext", QPalette.ButtonText) + self._setPalette(confParser,cnfSec,"brighttext", QPalette.BrightText) + + ## GUI + cnfSec = "GUI" + if confParser.has_section(cnfSec): + self.treeWCount = self._loadColour(confParser,cnfSec,"treewordcount") + self.statNone = self._loadColour(confParser,cnfSec,"statusnone") + self.statUnsaved = self._loadColour(confParser,cnfSec,"statusunsaved") + self.statSaved = self._loadColour(confParser,cnfSec,"statussaved") + + # Apply Styles + qApp.setStyleSheet(cssData) + qApp.setPalette(self.guiPalette) + + logger.info("Loaded theme '%s'" % self.guiTheme) + + return True + + def loadSyntax(self): + + confParser = configparser.ConfigParser() + try: + confParser.read_file(open(self.syntaxFile)) + except Exception as e: + logger.error("Could not load syntax colours from: %s" % self.syntaxFile) + return False + + ## Main + cnfSec = "Main" + if confParser.has_section(cnfSec): + self.syntaxName = self._parseLine(confParser,cnfSec,"name","") + self.syntaxAuthor = self._parseLine(confParser,cnfSec,"author","") + self.syntaxCredit = self._parseLine(confParser,cnfSec,"credit","") + self.syntaxUrl = self._parseLine(confParser,cnfSec,"url", "") ## Syntax cnfSec = "Syntax" if confParser.has_section(cnfSec): + self.colBack = self._loadColour(confParser,cnfSec,"background") self.colText = self._loadColour(confParser,cnfSec,"text") self.colLink = self._loadColour(confParser,cnfSec,"link") self.colHead = self._loadColour(confParser,cnfSec,"headertext") @@ -117,6 +201,8 @@ class Theme: self.colTagErr = self._loadColour(confParser,cnfSec,"tagerror") self.colRepTag = self._loadColour(confParser,cnfSec,"replacetag") + logger.info("Loaded syntax theme '%s'" % self.guiSyntax) + return True def listThemes(self): @@ -125,14 +211,14 @@ class Theme: return self.themeList confParser = configparser.ConfigParser() - for themeDir in listdir(self.mainConf.themeRoot): - themeConf = path.join(self.mainConf.themeRoot, themeDir, self.confName) + for themeDir in listdir(path.join(self.mainConf.themeRoot, self.guiPath)): + themeConf = path.join(self.mainConf.themeRoot, self.guiPath, 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 [] + continue themeName = "" if confParser.has_section("Main"): themeName = confParser.get("Main","name") @@ -140,8 +226,38 @@ class Theme: if themeName != "": self.themeList.append((themeDir, themeName)) + self.themeList = sorted(self.themeList, key=lambda x: x[1]) + return self.themeList + def listSyntax(self): + + if len(self.syntaxList) > 0: + return self.syntaxList + + confParser = configparser.ConfigParser() + syntaxDir = path.join(self.mainConf.themeRoot, self.syntaxPath) + for syntaxFile in listdir(syntaxDir): + syntaxPath = path.join(syntaxDir, syntaxFile) + if not path.isfile(syntaxPath): + continue + logger.verbose("Checking theme syntax for '%s'" % syntaxFile) + try: + confParser.read_file(open(syntaxPath)) + except Exception as e: + self.theParent.makeAlert(["Could not load syntax file",str(e)],nwAlert.ERROR) + return [] + syntaxName = "" + if confParser.has_section("Main"): + syntaxName = confParser.get("Main","name") + if len(syntaxFile) > 5 and syntaxName != "": + self.syntaxList.append((syntaxFile[:-5], syntaxName)) + logger.verbose("Syntax name is '%s'" % syntaxName) + + self.syntaxList = sorted(self.syntaxList, key=lambda x: x[1]) + + return self.syntaxList + ## # Internal Functions ## @@ -162,4 +278,25 @@ class Theme: outData = [0,0,0] return outData + def _setPalette(self, confParser, cnfSec, cnfName, paletteVal): + if confParser.has_option(cnfSec,cnfName): + inData = confParser.get(cnfSec,cnfName).split(",") + readCol = [] + try: + readCol.append(int(inData[0])) + readCol.append(int(inData[1])) + readCol.append(int(inData[2])) + except: + logger.error("Could not load theme colours for '%s' from config file" % cnfName) + return + if len(readCol) == 3: + self.guiPalette.setColor(paletteVal, QColor(*readCol)) + return + + def _parseLine(self, confParser, cnfSec, cnfName, cnfDefault): + if confParser.has_section(cnfSec): + if confParser.has_option(cnfSec, cnfName): + return confParser.get(cnfSec, cnfName) + return cnfDefault + # End Class Theme diff --git a/nw/themes/default_dark/styles.css b/nw/themes/default_dark/styles.css deleted file mode 100644 index c81aecf3..00000000 --- a/nw/themes/default_dark/styles.css +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Default Theme: Dark - */ - -* { - background-color: #999999; -} - -QTextEdit { - background-color: #141414; - color: #c7cfd0; -} - -QTextBrowser { - background-color: #141414; - color: #c7cfd0; -} - -QTreeView, QHeaderView { - font-size: 13px; -} diff --git a/nw/themes/default_light/theme.conf b/nw/themes/default_light/theme.conf deleted file mode 100644 index b3d0d5be..00000000 --- a/nw/themes/default_light/theme.conf +++ /dev/null @@ -1,18 +0,0 @@ -[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 diff --git a/nw/themes/default_light/styles.css b/nw/themes/gui/default/style.qss similarity index 100% rename from nw/themes/default_light/styles.css rename to nw/themes/gui/default/style.qss diff --git a/nw/themes/gui/default/theme.conf b/nw/themes/gui/default/theme.conf new file mode 100644 index 00000000..004b811d --- /dev/null +++ b/nw/themes/gui/default/theme.conf @@ -0,0 +1,2 @@ +[Main] +name = Default System Theme diff --git a/nw/themes/gui/default_dark/styles.qss b/nw/themes/gui/default_dark/styles.qss new file mode 100644 index 00000000..6c847eb6 --- /dev/null +++ b/nw/themes/gui/default_dark/styles.qss @@ -0,0 +1,7 @@ +/** + * Default Theme: Dark + */ + +QTreeView, QHeaderView { + font-size: 13px; +} diff --git a/nw/themes/gui/default_dark/theme.conf b/nw/themes/gui/default_dark/theme.conf new file mode 100644 index 00000000..65bf5f1e --- /dev/null +++ b/nw/themes/gui/default_dark/theme.conf @@ -0,0 +1,23 @@ +[Main] +name = Default Dark Theme +author = Veronica Berglyd Olsen +credit = Veronica Berglyd Olsen +url = https://github.com/vkbo/novelWriter + +[Palette] +window = 54, 54, 54 +windowtext = 174, 174, 174 +base = 62, 62, 62 +alternatebase = 67, 67, 67 +text = 174, 174, 174 +tooltipbase = 255, 255, 192 +tooltiptext = 21, 21, 13 +button = 62, 62, 62 +buttontext = 174, 174, 174 +brighttext = 174, 174, 174 + +[GUI] +treewordcount = 197, 200, 198 +statusnone = 150, 152, 150 +statussaved = 39, 135, 78 +statusunsaved = 138, 32, 32 diff --git a/nw/themes/default_dark/theme.conf b/nw/themes/syntax/default_dark.conf similarity index 93% rename from nw/themes/default_dark/theme.conf rename to nw/themes/syntax/default_dark.conf index 86b04b45..8d1cd6b4 100644 --- a/nw/themes/default_dark/theme.conf +++ b/nw/themes/syntax/default_dark.conf @@ -2,6 +2,7 @@ name = Default Dark [Syntax] +background = 54, 54, 54 text = 199, 207, 208 link = 184, 200, 0 headertext = 0, 155, 200 diff --git a/nw/themes/syntax/default_light.conf b/nw/themes/syntax/default_light.conf new file mode 100644 index 00000000..709a1ab2 --- /dev/null +++ b/nw/themes/syntax/default_light.conf @@ -0,0 +1,19 @@ +[Main] +name = Default Light + +[Syntax] +background = 255, 255, 255 +text = 0, 0, 0 +link = 0, 0, 200 +headertext = 0, 100, 00 +headertag = 50, 100, 50 +emphasis = 150, 110, 30 +straightquotes = 200, 0, 0 +doublequotes = 0, 0, 200 +singlequotes = 0, 0, 200 +hidden = 100, 100, 100 +keyword = 200, 50, 50 +value = 50, 150, 50 +spellcheckline = 200, 0, 0 +tagerror = 0, 150, 0 +replacetag = 0, 150, 0 diff --git a/nw/themes/syntax/tomorrow.conf b/nw/themes/syntax/tomorrow.conf new file mode 100644 index 00000000..93f16598 --- /dev/null +++ b/nw/themes/syntax/tomorrow.conf @@ -0,0 +1,42 @@ +## +# Theme: Tomorrow +# Source: https://github.com/chriskempson/tomorrow-theme +# Credit: Chris Kempson +## +# Colours: +# Background = 2d2d2d : 45, 45, 45 +# Current Line = 393939 : 57, 57, 57 +# Selection = 515151 : 81, 81, 81 +# Foreground = cccccc : 204, 204, 204 +# Comment = 999999 : 153, 153, 153 +# Red = f2777a : 242, 119, 122 +# Orange = f99157 : 249, 145, 57 +# Yellow = ffcc66 : 255, 204, 102 +# Green = 99cc99 : 153, 204, 153 +# Aqua = 66cccc : 102, 204, 204 +# Blue = 6699cc : 102, 153, 204 +# Purple = cc99cc : 204, 153, 204 +## + +[Main] +name = Tomorrow +author = Veronica Berglyd Olsen +credit = Chris Kempson +url = https://github.com/chriskempson/tomorrow-theme + +[Syntax] +background = 45, 45, 45 +text = 204, 204, 204 +link = 102, 153, 204 +headertext = 102, 153, 204 +headertag = 102, 153, 204 +emphasis = 249, 145, 57 +straightquotes = 242, 119, 122 +doublequotes = 153, 204, 153 +singlequotes = 255, 204, 102 +hidden = 153, 153, 153 +keyword = 242, 119, 122 +value = 204, 153, 204 +spellcheckline = 242, 119, 122 +tagerror = 153, 204, 153 +replacetag = 102, 204, 204 diff --git a/nw/themes/syntax/tomorrow_night.conf b/nw/themes/syntax/tomorrow_night.conf new file mode 100644 index 00000000..09966ff0 --- /dev/null +++ b/nw/themes/syntax/tomorrow_night.conf @@ -0,0 +1,42 @@ +## +# Theme: Tomorrow Night +# Source: https://github.com/chriskempson/tomorrow-theme +# Credit: Chris Kempson +## +# Colours: +# Background = 1d1f21 : 29, 31, 33 +# Current Line = 282a2e : 40, 42, 46 +# Selection = 373b41 : 55, 59. 65 +# Foreground = c5c8c6 : 197, 200, 198 +# Comment = 969896 : 150, 152, 150 +# Red = cc6666 : 204, 102, 102 +# Orange = de935f : 222, 147, 95 +# Yellow = f0c674 : 240, 198, 116 +# Green = b5bd68 : 181, 189, 104 +# Aqua = 8abeb7 : 138, 190, 183 +# Blue = 81a2be : 129, 162, 190 +# Purple = b294bb : 178, 148, 187 +## + +[Main] +name = Tomorrow Night +author = Veronica Berglyd Olsen +credit = Chris Kempson +url = https://github.com/chriskempson/tomorrow-theme + +[Syntax] +background = 29, 31, 33 +text = 197, 200, 198 +link = 129, 162, 190 +headertext = 129, 162, 190 +headertag = 129, 162, 190 +emphasis = 222, 147, 95 +straightquotes = 204, 102, 102 +doublequotes = 181, 189, 104 +singlequotes = 240, 198, 116 +hidden = 150, 152, 150 +keyword = 204, 102, 102 +value = 178, 148, 187 +spellcheckline = 204, 102, 102 +tagerror = 181, 189, 104 +replacetag = 138, 190, 183 diff --git a/nw/themes/syntax/tomorrow_night_blue.conf b/nw/themes/syntax/tomorrow_night_blue.conf new file mode 100644 index 00000000..d05a757b --- /dev/null +++ b/nw/themes/syntax/tomorrow_night_blue.conf @@ -0,0 +1,42 @@ +## +# Theme: Tomorrow Night Blue +# Source: https://github.com/chriskempson/tomorrow-theme +# Credit: Chris Kempson +## +# Colours: +# Background = 002451 : 0, 36, 81 +# Current Line = 00346e : 0, 52, 110 +# Selection = 003f8e : 0, 63, 142 +# Foreground = ffffff : 255, 255, 255 +# Comment = 7285b7 : 114, 133, 183 +# Red = ff9da4 : 255, 157, 164 +# Orange = ffc58f : 255, 197, 143 +# Yellow = ffeead : 255, 238, 173 +# Green = d1f1a9 : 209, 241, 169 +# Aqua = 99ffff : 153, 255, 255 +# Blue = bbdaff : 187, 218, 255 +# Purple = ebbbff : 235, 187, 255 +## + +[Main] +name = Tomorrow Night Blue +author = Veronica Berglyd Olsen +credit = Chris Kempson +url = https://github.com/chriskempson/tomorrow-theme + +[Syntax] +background = 0, 36, 81 +text = 255, 255, 255 +link = 187, 218, 255 +headertext = 187, 218, 255 +headertag = 187, 218, 255 +emphasis = 255, 197, 143 +straightquotes = 255, 157, 164 +doublequotes = 209, 241, 169 +singlequotes = 255, 238, 173 +hidden = 114, 133, 183 +keyword = 255, 157, 164 +value = 235, 187, 255 +spellcheckline = 255, 157, 164 +tagerror = 209, 241, 169 +replacetag = 153, 255, 255 diff --git a/nw/themes/syntax/tomorrow_night_bright.conf b/nw/themes/syntax/tomorrow_night_bright.conf new file mode 100644 index 00000000..0d9c6c3a --- /dev/null +++ b/nw/themes/syntax/tomorrow_night_bright.conf @@ -0,0 +1,42 @@ +## +# Theme: Tomorrow Night Bright +# Source: https://github.com/chriskempson/tomorrow-theme +# Credit: Chris Kempson +## +# Colours: +# Background = 000000 : 0, 0, 0 +# Current Line = 2a2a2a : 42, 42, 42 +# Selection = 424242 : 66, 66, 66 +# Foreground = eaeaea : 234, 234, 234 +# Comment = 969896 : 150, 152, 150 +# Red = d54e53 : 213, 78, 83 +# Orange = e78c45 : 231, 140, 69 +# Yellow = e7c547 : 231, 197, 71 +# Green = b9ca4a : 185, 202, 74 +# Aqua = 70c0b1 : 112, 192, 177 +# Blue = 7aa6da : 122, 166, 218 +# Purple = c397d8 : 195, 151, 216 +## + +[Main] +name = Tomorrow Night Bright +author = Veronica Berglyd Olsen +credit = Chris Kempson +url = https://github.com/chriskempson/tomorrow-theme + +[Syntax] +background = 0, 0, 0 +text = 234, 234, 234 +link = 122, 166, 218 +headertext = 122, 166, 218 +headertag = 122, 166, 218 +emphasis = 231, 140, 69 +straightquotes = 213, 78, 83 +doublequotes = 185, 202, 74 +singlequotes = 231, 197, 71 +hidden = 150, 152, 150 +keyword = 213, 78, 83 +value = 195, 151, 216 +spellcheckline = 213, 78, 83 +tagerror = 185, 202, 74 +replacetag = 112, 192, 177 diff --git a/nw/themes/syntax/tomorrow_night_eighties.conf b/nw/themes/syntax/tomorrow_night_eighties.conf new file mode 100644 index 00000000..5bd0c222 --- /dev/null +++ b/nw/themes/syntax/tomorrow_night_eighties.conf @@ -0,0 +1,42 @@ +## +# Theme: Tomorrow Night Eighties +# Source: https://github.com/chriskempson/tomorrow-theme +# Credit: Chris Kempson +## +# Colours: +# Background = 2d2d2d : 45, 45, 45 +# Current Line = 393939 : 57, 57, 57 +# Selection = 515151 : 81, 81, 81 +# Foreground = cccccc : 204, 204, 204 +# Comment = 999999 : 153, 153, 153 +# Red = f2777a : 242, 119, 122 +# Orange = f99157 : 249, 145, 57 +# Yellow = ffcc66 : 255, 204, 102 +# Green = 99cc99 : 153, 204, 153 +# Aqua = 66cccc : 102, 204, 204 +# Blue = 6699cc : 102, 153, 204 +# Purple = cc99cc : 204, 153, 204 +## + +[Main] +name = Tomorrow Night Eighties +author = Veronica Berglyd Olsen +credit = Chris Kempson +url = https://github.com/chriskempson/tomorrow-theme + +[Syntax] +background = 45, 45, 45 +text = 204, 204, 204 +link = 102, 153, 204 +headertext = 102, 153, 204 +headertag = 102, 153, 204 +emphasis = 249, 145, 57 +straightquotes = 242, 119, 122 +doublequotes = 153, 204, 153 +singlequotes = 255, 204, 102 +hidden = 153, 153, 153 +keyword = 242, 119, 122 +value = 204, 153, 204 +spellcheckline = 242, 119, 122 +tagerror = 153, 204, 153 +replacetag = 102, 204, 204 diff --git a/sample/sampleNovel/nwProject.nwx b/sample/sampleNovel/nwProject.nwx index 6b667a58..0081d96a 100644 --- a/sample/sampleNovel/nwProject.nwx +++ b/sample/sampleNovel/nwProject.nwx @@ -1,5 +1,5 @@ - + Sample Project Sample Project @@ -9,7 +9,7 @@ True 636b6aa9b697b - bc0cbd2a407f3 + 636b6aa9b697b 581 B @@ -80,7 +80,7 @@ 736 137 6 - 424 + 69 New File diff --git a/tests/reference/novelwriter.conf b/tests/reference/novelwriter.conf index 0f0562f9..c0eb784e 100644 --- a/tests/reference/novelwriter.conf +++ b/tests/reference/novelwriter.conf @@ -1,6 +1,7 @@ [Main] -timestamp = 2019-06-15 12:26:17 -theme = default_dark +timestamp = 2019-06-15 23:10:43 +theme = default +syntax = default_light [Sizes] geometry = 1100, 650