diff --git a/nw/config.py b/nw/config.py
index a12aaa9a..1627270f 100644
--- a/nw/config.py
+++ b/nw/config.py
@@ -25,6 +25,11 @@ class Config:
WIN_WIDTH = 0
WIN_HEIGHT = 1
+ CNF_STR = 0
+ CNF_INT = 1
+ CNF_BOOL = 2
+ CNF_LIST = 3
+
def __init__(self):
# Set Application Variables
@@ -38,6 +43,7 @@ class Config:
self.confFile = None
self.homePath = None
self.appPath = None
+ self.appRoot = None
self.guiPath = None
self.themePath = None
@@ -60,6 +66,7 @@ class Config:
self.textWidth = 600
self.textMargin = [40, 40]
self.textSize = 13
+ self.tabWidth = 40
self.doJustify = True
self.autoSelect = True
self.doReplace = True
@@ -68,7 +75,7 @@ class Config:
self.doReplaceDash = True
self.doReplaceDots = True
self.wordCountTimer = 5.0
-
+
self.fmtDoubleQuotes = ["“","”"]
self.fmtSingleQuotes = ["‘","’"]
self.fmtApostrophe = "’"
@@ -95,6 +102,7 @@ class Config:
self.confFile = self.appHandle+".conf"
self.homePath = path.expanduser("~")
self.appPath = path.dirname(__file__)
+ self.appRoot = path.join(self.appPath,path.pardir)
self.guiPath = path.join(self.appPath,"gui")
self.themePath = path.join(self.appPath,"themes")
@@ -117,140 +125,105 @@ class Config:
def loadConfig(self):
logger.debug("Loading config file")
- confParser = configparser.ConfigParser()
+ cnfParse = configparser.ConfigParser()
try:
- confParser.read_file(open(path.join(self.confPath,self.confFile)))
+ cnfParse.read_file(open(path.join(self.confPath,self.confFile)))
except Exception as e:
logger.error("Could not load config file")
return False
- # Get options
-
## Main
cnfSec = "Main"
- if confParser.has_section(cnfSec):
- if confParser.has_option(cnfSec,"theme"):
- self.guiTheme = confParser.get(cnfSec,"theme")
+ self.guiTheme = self._parseLine(cnfParse, cnfSec, "theme", self.CNF_STR, self.guiTheme)
## Sizes
cnfSec = "Sizes"
- if confParser.has_section(cnfSec):
- if confParser.has_option(cnfSec,"geometry"):
- self.winGeometry = self.unpackList(
- confParser.get(cnfSec,"geometry"), 2, self.winGeometry
- )
- if confParser.has_option(cnfSec,"treecols"):
- self.treeColWidth = self.unpackList(
- confParser.get(cnfSec,"treecols"), 3, self.treeColWidth
- )
- if confParser.has_option(cnfSec,"mainpane"):
- self.mainPanePos = self.unpackList(
- confParser.get(cnfSec,"mainpane"), 2, self.mainPanePos
- )
- if confParser.has_option(cnfSec,"docpane"):
- self.docPanePos = self.unpackList(
- confParser.get(cnfSec,"docpane"), 2, self.docPanePos
- )
+ self.winGeometry = self._parseLine(cnfParse, cnfSec, "geometry", self.CNF_LIST, self.winGeometry)
+ self.treeColWidth = self._parseLine(cnfParse, cnfSec, "treecols", self.CNF_LIST, self.treeColWidth)
+ self.mainPanePos = self._parseLine(cnfParse, cnfSec, "mainpane", self.CNF_LIST, self.mainPanePos)
+ self.docPanePos = self._parseLine(cnfParse, cnfSec, "docpane", self.CNF_LIST, self.docPanePos)
## Project
cnfSec = "Project"
- if confParser.has_section(cnfSec):
- if confParser.has_option(cnfSec,"autosaveproject"):
- self.autoSaveProj = confParser.getint(cnfSec,"autosaveproject")
- if confParser.has_option(cnfSec,"autosavedoc"):
- self.autoSaveDoc = confParser.getint(cnfSec,"autosavedoc")
+ self.autoSaveProj = self._parseLine(cnfParse, cnfSec, "autosaveproject", self.CNF_INT, self.autoSaveProj)
+ self.autoSaveDoc = self._parseLine(cnfParse, cnfSec, "autosavedoc", self.CNF_INT, self.autoSaveDoc)
## Editor
cnfSec = "Editor"
- if confParser.has_section(cnfSec):
- if confParser.has_option(cnfSec,"fixedwidth"):
- self.textFixedW = confParser.getboolean(cnfSec,"fixedwidth")
- if confParser.has_option(cnfSec,"width"):
- self.textWidth = confParser.getint(cnfSec,"width")
- if confParser.has_option(cnfSec,"margins"):
- self.textMargin = self.unpackList(
- confParser.get(cnfSec,"margins"), 2, self.textMargin
- )
- if confParser.has_option(cnfSec,"textsize"):
- self.textSize = confParser.getint(cnfSec,"textsize")
- if confParser.has_option(cnfSec,"justify"):
- self.doJustify = confParser.getboolean(cnfSec,"justify")
- if confParser.has_option(cnfSec,"autoselect"):
- self.autoSelect = confParser.getboolean(cnfSec,"autoselect")
- if confParser.has_option(cnfSec,"autoreplace"):
- self.doReplace = confParser.getboolean(cnfSec,"autoreplace")
- if confParser.has_option(cnfSec,"repsquotes"):
- self.doReplaceSQuote = confParser.getboolean(cnfSec,"repsquotes")
- if confParser.has_option(cnfSec,"repdquotes"):
- self.doReplaceDQuote = confParser.getboolean(cnfSec,"repdquotes")
- if confParser.has_option(cnfSec,"repdash"):
- self.doReplaceDash = confParser.getboolean(cnfSec,"repdash")
- if confParser.has_option(cnfSec,"repdots"):
- self.doReplaceDots = confParser.getboolean(cnfSec,"repdots")
- if confParser.has_option(cnfSec,"spellcheck"):
- self.spellLanguage = confParser.get(cnfSec,"spellcheck")
+ 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)
## Path
cnfSec = "Path"
- if confParser.has_section(cnfSec):
- for i in range(10):
- if confParser.has_option(cnfSec,"recent%d" % i):
- self.recentList[i] = confParser.get(cnfSec,"recent%d" % i)
+ for i in range(10):
+ self.recentList[i] = self._parseLine(cnfParse, cnfSec, "recent%d" % i,self.CNF_STR, self.recentList[i])
return True
def saveConfig(self):
logger.debug("Saving config file")
- confParser = configparser.ConfigParser()
+ cnfParse = configparser.ConfigParser()
# Set options
## Main
cnfSec = "Main"
- confParser.add_section(cnfSec)
- confParser.set(cnfSec,"timestamp", datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
- confParser.set(cnfSec,"theme", str(self.guiTheme))
+ cnfParse.add_section(cnfSec)
+ cnfParse.set(cnfSec,"timestamp", datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
+ cnfParse.set(cnfSec,"theme", str(self.guiTheme))
## Sizes
cnfSec = "Sizes"
- confParser.add_section(cnfSec)
- confParser.set(cnfSec,"geometry", self.packList(self.winGeometry))
- confParser.set(cnfSec,"treecols", self.packList(self.treeColWidth))
- confParser.set(cnfSec,"mainpane", self.packList(self.mainPanePos))
- confParser.set(cnfSec,"docpane", self.packList(self.docPanePos))
+ cnfParse.add_section(cnfSec)
+ cnfParse.set(cnfSec,"geometry", self._packList(self.winGeometry))
+ cnfParse.set(cnfSec,"treecols", self._packList(self.treeColWidth))
+ cnfParse.set(cnfSec,"mainpane", self._packList(self.mainPanePos))
+ cnfParse.set(cnfSec,"docpane", self._packList(self.docPanePos))
## Project
cnfSec = "Project"
- confParser.add_section(cnfSec)
- confParser.set(cnfSec,"autosaveproject", str(self.autoSaveProj))
- confParser.set(cnfSec,"autosavedoc", str(self.autoSaveDoc))
+ cnfParse.add_section(cnfSec)
+ cnfParse.set(cnfSec,"autosaveproject", str(self.autoSaveProj))
+ cnfParse.set(cnfSec,"autosavedoc", str(self.autoSaveDoc))
## Editor
cnfSec = "Editor"
- confParser.add_section(cnfSec)
- confParser.set(cnfSec,"fixedwidth", str(self.textFixedW))
- confParser.set(cnfSec,"width", str(self.textWidth))
- confParser.set(cnfSec,"margins", self.packList(self.textMargin))
- confParser.set(cnfSec,"textsize", str(self.textSize))
- confParser.set(cnfSec,"justify", str(self.doJustify))
- confParser.set(cnfSec,"autoselect", str(self.autoSelect))
- confParser.set(cnfSec,"autoreplace",str(self.doReplace))
- confParser.set(cnfSec,"repsquotes", str(self.doReplaceSQuote))
- confParser.set(cnfSec,"repdquotes", str(self.doReplaceDQuote))
- confParser.set(cnfSec,"repdash", str(self.doReplaceDash))
- confParser.set(cnfSec,"repdots", str(self.doReplaceDots))
- confParser.set(cnfSec,"spellcheck", str(self.spellLanguage))
+ 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))
## Path
cnfSec = "Path"
- confParser.add_section(cnfSec)
+ cnfParse.add_section(cnfSec)
for i in range(10):
- confParser.set(cnfSec,"recent%d" % i, str(self.recentList[i]))
+ cnfParse.set(cnfSec,"recent%d" % i, str(self.recentList[i]))
# Write config file
try:
- confParser.write(open(path.join(self.confPath,self.confFile),"w"))
+ cnfParse.write(open(path.join(self.confPath,self.confFile),"w"))
self.confChanged = False
except Exception as e:
logger.error("Could not save config file")
@@ -258,19 +231,6 @@ class Config:
return True
- def unpackList(self, inStr, listLen, listDefault, castTo=int):
- inData = inStr.split(",")
- outData = []
- for i in range(listLen):
- try:
- outData.append(castTo(inData[i]))
- except:
- outData.append(listDefault[i])
- return outData
-
- def packList(self, inData):
- return ", ".join(str(inVal) for inVal in inData)
-
##
# Setters
##
@@ -316,4 +276,36 @@ class Config:
self.confChanged = True
return True
+ ##
+ # Internal Functions
+ ##
+
+ def _unpackList(self, inStr, listLen, listDefault, castTo=int):
+ inData = inStr.split(",")
+ outData = []
+ for i in range(listLen):
+ try:
+ outData.append(castTo(inData[i]))
+ except:
+ outData.append(listDefault[i])
+ return outData
+
+ def _packList(self, inData):
+ return ", ".join(str(inVal) for inVal in inData)
+
+ def _parseLine(self, cnfParse, cnfSec, cnfName, cnfType, cnfDefault):
+ if cnfParse.has_section(cnfSec):
+ if cnfParse.has_option(cnfSec, cnfName):
+ if cnfType == self.CNF_STR:
+ return cnfParse.get(cnfSec, cnfName)
+ elif cnfType == self.CNF_INT:
+ return cnfParse.getint(cnfSec, cnfName)
+ elif cnfType == self.CNF_BOOL:
+ return cnfParse.getboolean(cnfSec, cnfName)
+ elif cnfType == self.CNF_LIST:
+ return self._unpackList(
+ cnfParse.get(cnfSec, cnfName), len(cnfDefault), cnfDefault
+ )
+ return cnfDefault
+
# End Class Config
diff --git a/nw/constants.py b/nw/constants.py
index 7dc39f05..478a7f5f 100644
--- a/nw/constants.py
+++ b/nw/constants.py
@@ -12,6 +12,15 @@
from nw.enum import nwItemClass, nwItemLayout
+class nwFiles():
+
+ APP_ICON = "novelWriter.svg"
+ PROJ_FILE = "nwProject.nwx"
+ PROJ_DICT = "wordlist.txt"
+ SESS_INFO = "sessionInfo.log"
+
+# END Class nwFiles
+
class nwLabels():
CLASS_NAME = {
@@ -59,5 +68,4 @@ class nwLabels():
nwItemLayout.NOTE : "Nt",
}
-
-# END nwLabels
+# END Class nwLabels
diff --git a/nw/gui/aboutview.py b/nw/gui/aboutview.py
deleted file mode 100644
index fa3e747c..00000000
--- a/nw/gui/aboutview.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# -*- coding: utf-8 -*-
-"""novelWriter GUI About View
-
- novelWriter – GUI About View
-==============================
- Class holding the tab viewing the about information
-
- File History:
- Created: 2018-10-02 [0.0.1]
-
-"""
-
-import logging
-import nw
-
-from os import path
-from PyQt5.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QLabel
-from PyQt5.QtSvg import QSvgWidget
-from PyQt5.QtCore import Qt, QSize
-from PyQt5.QtGui import QFont
-
-logger = logging.getLogger(__name__)
-
-class GuiAboutView(QWidget):
-
- def __init__(self):
- QWidget.__init__(self)
-
- logger.debug("Initialising AboutView ...")
- self.mainConf = nw.CONFIG
- self.innerBox = QHBoxLayout()
- self.outerBox = QVBoxLayout()
-
- logoPath = path.abspath(path.join(self.mainConf.appPath,"..","novelWriter.svg"))
- logger.verbose("Loading image: %s" % logoPath)
- nwLogo = QSvgWidget(logoPath)
- nwLogo.setFixedSize(QSize(300,300))
-
- nwName = QLabel()
- nwName.setText(nw.__package__)
- nwName.setAlignment(Qt.AlignCenter)
- fnName = QFont()
- fnName.setPointSize(22)
- fnName.setBold(True)
- nwName.setFont(fnName)
-
- nwVersion = QLabel()
- nwVersion.setText("Version %s" % nw.__version__)
- nwVersion.setAlignment(Qt.AlignCenter)
-
- nwCredits = QLabel()
- nwCredits.setText("Created By: %s" % ",".join(nw.__credits__))
- nwCredits.setAlignment(Qt.AlignCenter)
-
- nwWebsite = QLabel()
- nwWebsite.setText("%s" % (nw.__website__,nw.__website__))
- nwWebsite.setOpenExternalLinks(True)
- nwWebsite.setAlignment(Qt.AlignCenter)
-
- self.outerBox.addStretch(1)
- self.innerBox.addStretch(1)
- self.innerBox.addWidget(nwLogo)
- self.innerBox.addStretch(1)
- self.outerBox.addLayout(self.innerBox)
- self.outerBox.addWidget(nwName)
- self.outerBox.addWidget(nwVersion)
- self.outerBox.addWidget(nwCredits)
- self.outerBox.addWidget(nwWebsite)
- self.outerBox.addStretch(1)
-
- self.setLayout(self.outerBox)
-
- logger.debug("AboutView initialisation complete")
-
- return
-
-# END Class GuiAboutView
diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py
index 7ba063d7..c708536e 100644
--- a/nw/gui/doceditor.py
+++ b/nw/gui/doceditor.py
@@ -104,8 +104,12 @@ class GuiDocEditor(QTextEdit):
mTB = self.mainConf.textMargin[0]
mLR = self.mainConf.textMargin[1]
self.setViewportMargins(mLR,mTB,mLR,mTB)
+ theOpt = QTextOption()
+ if self.mainConf.tabWidth is not None:
+ theOpt.setTabStopDistance(self.mainConf.tabWidth)
if self.mainConf.doJustify:
- self.theDoc.setDefaultTextOption(QTextOption(Qt.AlignJustify))
+ theOpt.setAlignment(Qt.AlignJustify)
+ self.theDoc.setDefaultTextOption(theOpt)
return True
##
@@ -376,6 +380,7 @@ class GuiDocEditor(QTextEdit):
self.paraCount = self.wCounter.paraCount
self.theParent.statusBar.setCounts(self.charCount,self.wordCount,self.paraCount)
self.theParent.treeView.propagateCount(tHandle, self.wordCount)
+ self.theParent.treeView.projectWordCount()
return
diff --git a/nw/gui/dochighlight.py b/nw/gui/dochighlight.py
index 4db6267a..697b2dea 100644
--- a/nw/gui/dochighlight.py
+++ b/nw/gui/dochighlight.py
@@ -194,13 +194,14 @@ class GuiDocHighlighter(QSyntaxHighlighter):
self.setCurrentBlockState(0)
- if self.theDict is None or not self.spellCheck:
+ if self.theDict is None or not self.spellCheck or theText.startswith("@"):
return
rxSpell = self.spellRx.globalMatch(theText.replace("_"," "), 0)
while rxSpell.hasNext():
rxMatch = rxSpell.next()
if not self.theDict.check(rxMatch.captured(0)):
+ if rxMatch.captured(0) == rxMatch.captured(0).upper(): continue
xPos = rxMatch.capturedStart(0)
xLen = rxMatch.capturedLength(0)
spFmt = self.format(xPos)
diff --git a/nw/gui/doctree.py b/nw/gui/doctree.py
index da074375..280fa09a 100644
--- a/nw/gui/doctree.py
+++ b/nw/gui/doctree.py
@@ -50,7 +50,7 @@ class GuiDocTree(QTreeWidget):
self.setExpandsOnDoubleClick(True)
self.setIndentation(13)
self.setColumnCount(4)
- self.setHeaderLabels(["Name","Count","Flags","Handle"])
+ self.setHeaderLabels(["Name","Words","Flags","Handle"])
if not self.debugGUI:
self.hideColumn(self.C_HANDLE)
@@ -286,6 +286,18 @@ class GuiDocTree(QTreeWidget):
self.propagateCount(pHandle, pCount, nDepth+1)
return
+ def projectWordCount(self):
+ nWords = 0
+ for n in range(self.topLevelItemCount()):
+ tItem = self.topLevelItem(n)
+ if tItem == self.orphRoot:
+ continue
+ nWords += int(tItem.text(self.C_COUNT))
+ self.theProject.setProjectWordCount(nWords)
+ sWords = self.theProject.getSessionWordCount()
+ self.theParent.statusBar.setStats(nWords,sWords)
+ return
+
def buildTree(self):
self.clear()
for nwItem in self.theProject.getProjectItems():
diff --git a/nw/gui/mainmenu.py b/nw/gui/mainmenu.py
index 7cb5274d..981933ee 100644
--- a/nw/gui/mainmenu.py
+++ b/nw/gui/mainmenu.py
@@ -253,6 +253,13 @@ class GuiMainMenu(QMenuBar):
menuItem.triggered.connect(self.theParent.saveDocument)
self.docuMenu.addAction(menuItem)
+ # Document > Close
+ menuItem = QAction(QIcon.fromTheme("document-revert"), "Close Document", self)
+ menuItem.setStatusTip("Close Current Document")
+ menuItem.setShortcut("Ctrl+W")
+ menuItem.triggered.connect(self.theParent.closeDocEditor)
+ self.docuMenu.addAction(menuItem)
+
# Document > Separator
self.docuMenu.addSeparator()
diff --git a/nw/gui/statusbar.py b/nw/gui/statusbar.py
index 3e68690f..484e9519 100644
--- a/nw/gui/statusbar.py
+++ b/nw/gui/statusbar.py
@@ -13,6 +13,9 @@
import logging
import nw
+from time import time
+from PyQt5.QtCore import Qt, QTimer
+from PyQt5.QtGui import QIcon, QColor, QPixmap
from PyQt5.QtWidgets import QStatusBar, QLabel, QFrame
logger = logging.getLogger(__name__)
@@ -25,36 +28,74 @@ class GuiMainStatus(QStatusBar):
logger.debug("Initialising GuiMainStatus ...")
self.mainConf = nw.CONFIG
+ 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.boxStats = QLabel()
+ self.boxStats.setToolTip("Project Word Count | Session Word Count")
+
+ self.boxTime = QLabel("")
+ self.boxTime.setToolTip("Session Time")
+ self.boxTime.setAlignment(Qt.AlignRight)
+ self.boxTime.setMinimumWidth(80)
self.boxCounts = QLabel()
- self.boxCounts.setToolTip("Character, Word, Paragraph Count")
- self.boxCounts.setFrameStyle(QFrame.Panel | QFrame.Sunken);
- self.addPermanentWidget(self.boxCounts)
+ self.boxCounts.setToolTip("Document Character | Word | Paragraph Count")
- self.projChanged = QLabel("P")
+ self.projChanged = QLabel("")
+ self.projChanged.setFixedHeight(16)
+ self.projChanged.setFixedWidth(16)
self.projChanged.setToolTip("Project Changes Saved")
- self.projChanged.setFrameStyle(QFrame.Panel | QFrame.Sunken);
- self.addPermanentWidget(self.projChanged)
- self.docChanged = QLabel("D")
+ self.docChanged = QLabel("")
+ self.docChanged.setFixedHeight(16)
+ self.docChanged.setFixedWidth(16)
self.docChanged.setToolTip("Document Changes Saved")
- self.docChanged.setFrameStyle(QFrame.Panel | QFrame.Sunken);
- self.addPermanentWidget(self.docChanged)
self.boxDocHandle = QLabel()
self.boxDocHandle.setFrameStyle(QFrame.Panel | QFrame.Sunken);
+
+ # Add Them
+ self.addPermanentWidget(self.docChanged)
+ self.addPermanentWidget(self.boxCounts)
+ self.addPermanentWidget(QLabel(" "))
+ self.addPermanentWidget(self.projChanged)
+ self.addPermanentWidget(self.boxStats)
+ self.addPermanentWidget(self.boxTime)
if self.mainConf.debugGUI:
self.addPermanentWidget(self.boxDocHandle)
+ self.setSizeGripEnabled(True)
+
+ self.sessionTimer = QTimer()
+ self.sessionTimer.setInterval(1000)
+ self.sessionTimer.timeout.connect(self._updateTime)
+ self.sessionTimer.start()
+
logger.debug("GuiMainStatus initialisation complete")
+ self.clearStatus()
+
+ return
+
+ def clearStatus(self):
+ self.setRefTime(None)
+ self.setStats(0,0)
self.setCounts(0,0,0)
self.setDocHandleCount(None)
self.setProjectStatus(None)
self.setDocumentStatus(None)
+ self._updateTime()
+ return True
- self.setSizeGripEnabled(True)
-
+ def setRefTime(self, theTime):
+ self.refTime = theTime
return
def setStatus(self, theMessage, timeOut=10.0):
@@ -63,28 +104,32 @@ class GuiMainStatus(QStatusBar):
def setProjectStatus(self, isChanged):
if isChanged is None:
- self.projChanged.setStyleSheet("QLabel {background-color: rgba(120,120,120,1.0);}")
+ self.projChanged.setPixmap(self.iconGrey)
elif isChanged == True:
- self.projChanged.setStyleSheet("QLabel {background-color: rgba(120,120,40,1.0);}")
+ self.projChanged.setPixmap(self.iconYellow)
elif isChanged == False:
- self.projChanged.setStyleSheet("QLabel {background-color: rgba(40,120,0,1.0);}")
+ self.projChanged.setPixmap(self.iconGreen)
else:
- self.projChanged.setStyleSheet("QLabel {background-color: rgba(120,120,120,1.0);}")
+ self.projChanged.setPixmap(self.iconGrey)
return
def setDocumentStatus(self, isChanged):
if isChanged is None:
- self.docChanged.setStyleSheet("QLabel {background-color: rgba(120,120,120,1.0);}")
+ self.docChanged.setPixmap(self.iconGrey)
elif isChanged == True:
- self.docChanged.setStyleSheet("QLabel {background-color: rgba(120,120,40,1.0);}")
+ self.docChanged.setPixmap(self.iconYellow)
elif isChanged == False:
- self.docChanged.setStyleSheet("QLabel {background-color: rgba(40,120,0,1.0);}")
+ self.docChanged.setPixmap(self.iconGreen)
else:
- self.docChanged.setStyleSheet("QLabel {background-color: rgba(120,120,120,1.0);}")
+ self.docChanged.setPixmap(self.iconGrey)
+ return
+
+ def setStats(self, pWC, sWC):
+ self.boxStats.setText("Project: {:d} : {:d}".format(pWC,sWC))
return
def setCounts(self, cC, wC, pC):
- self.boxCounts.setText("C: {:n} W: {:n} P: {:n}".format(cC,wC,pC))
+ self.boxCounts.setText("Document: {:d} : {:d} : {:d}".format(cC,wC,pC))
return
def setDocHandleCount(self, theHandle):
@@ -94,4 +139,22 @@ class GuiMainStatus(QStatusBar):
self.boxDocHandle.setText("%13s" % theHandle)
return
+ ##
+ # Internal Functions
+ ##
+
+ def _updateTime(self):
+ if self.refTime is None:
+ theTime = "00:00:00"
+ else:
+ # This is much faster than using datetime format
+ tS = int(time() - self.refTime)
+ tM = int(tS/60)
+ tH = int(tM/60)
+ tM = tM - tH*60
+ tS = tS - tM*60 - tH*3600
+ theTime = "%02d:%02d:%02d" % (tH,tM,tS)
+ self.boxTime.setText(theTime)
+ return
+
# END Class GuiMainStatus
diff --git a/nw/gui/winmain.py b/nw/gui/winmain.py
index 6eabeeb9..0de1c27f 100644
--- a/nw/gui/winmain.py
+++ b/nw/gui/winmain.py
@@ -36,6 +36,7 @@ from nw.project.item import NWItem
from nw.convert.tokenizer import Tokenizer
from nw.convert.tohtml import ToHtml
from nw.enum import nwItemType, nwAlert
+from nw.constants import nwFiles
logger = logging.getLogger(__name__)
@@ -53,7 +54,7 @@ class GuiMain(QMainWindow):
self.resize(*self.mainConf.winGeometry)
self._setWindowTitle()
- self.setWindowIcon(QIcon(path.join(self.mainConf.appPath,"..","novelWriter.svg")))
+ self.setWindowIcon(QIcon(path.join(self.mainConf.appRoot, nwFiles.APP_ICON)))
self.theTheme.loadTheme()
# Main GUI Elements
@@ -139,43 +140,11 @@ class GuiMain(QMainWindow):
return
- def makeAlert(self, theMessage, theLevel=nwAlert.INFO):
- """Alert both the user and the logger at the same time. Message can be either a string or an
- array of strings. Severity level is 0 = info, 1 = warning, and 2 = error.
- """
-
- if isinstance(theMessage, list):
- popMsg = "
".join(theMessage)
- logMsg = theMessage
- else:
- popMsg = theMessage
- logMsg = [theMessage]
-
- msgBox = QMessageBox()
- if theLevel == nwAlert.INFO:
- for msgLine in logMsg:
- logger.info(msgLine)
- msgBox.information(self, "Information", popMsg)
- elif theLevel == nwAlert.WARN:
- for msgLine in logMsg:
- logger.warning(msgLine)
- msgBox.warning(self, "Warning", popMsg)
- elif theLevel == nwAlert.ERROR:
- for msgLine in logMsg:
- logger.error(msgLine)
- msgBox.critical(self, "Error", popMsg)
- elif theLevel == nwAlert.BUG:
- for msgLine in logMsg:
- logger.error(msgLine)
- popMsg += "
This is a bug!"
- msgBox.critical(self, "Internal Error", popMsg)
-
- return
-
def clearGUI(self):
self.treeView.clearTree()
self.docEditor.clearEditor()
self.closeDocViewer()
+ self.statusBar.clearStatus()
return True
##
@@ -211,19 +180,22 @@ class GuiMain(QMainWindow):
self.rebuildTree()
self.saveProject()
self.hasProject = True
+ self.statusBar.setRefTime(self.theProject.projOpened)
return True
def closeProject(self, isYes=False):
-
+ """Closes the project if one is open.
+ isYes is passed on from the close application event so the user doesn't get prompted twice.
+ """
if not self.hasProject:
+ # There is no project loaded, everything OK
return True
- if not isYes:
+ if self.mainConf.showGUI and not isYes:
msgBox = QMessageBox()
msgRes = msgBox.question(
- self, "Close Project",
- "Close current project?
Unsaved changes will be saved."
+ self, "Close Project", "Save changes and close current project?"
)
if msgRes != QMessageBox.Yes:
return False
@@ -235,29 +207,38 @@ class GuiMain(QMainWindow):
saveOK = True
if saveOK:
- self.theProject.clearProject()
+ self.theProject.closeProject()
self.clearGUI()
self.hasProject = False
-
+
return saveOK
def openProject(self, projFile=None):
-
+ """Open a project.
+ projFile is passed from the open recent projects menu, so can be set. If not, we pop the dialog.
+ """
if projFile is None:
projFile = self.openProjectDialog()
if projFile is None:
return False
+ # Make sure any open project is cleared out first before we load another one
if not self.closeProject():
return False
- self.theProject.openProject(projFile)
+ # Try to open the project
+ if not self.theProject.openProject(projFile):
+ return False
+
+ # Update GUI
self._setWindowTitle(self.theProject.projName)
self.rebuildTree()
- self.docEditor.setPwl(path.join(self.theProject.projMeta,"wordlist.txt"))
+ self.docEditor.setPwl(path.join(self.theProject.projMeta, nwFiles.PROJ_DICT))
self.docEditor.setSpellCheck(self.theProject.spellCheck)
+ self.statusBar.setRefTime(self.theProject.projOpened)
self.mainMenu.updateMenu()
+ # Restore previously open documents, if any
if self.theProject.lastEdited is not None:
self.openDocument(self.theProject.lastEdited)
if self.theProject.lastViewed is not None:
@@ -268,7 +249,9 @@ class GuiMain(QMainWindow):
return True
def saveProject(self):
-
+ """Save the current project.
+ """
+ # If the project is new, it may not have a path, so we need one
if self.theProject.projPath is None:
projPath = self.saveProjectDialog()
self.theProject.setProjectPath(projPath)
@@ -286,13 +269,14 @@ class GuiMain(QMainWindow):
##
def closeDocument(self):
- self.saveDocument()
+ if self.docEditor.docChanged:
+ self.saveDocument()
self.theDocument.clearDocument()
+ self.docEditor.clearEditor()
return True
def openDocument(self, tHandle):
- if self.docEditor.docChanged:
- self.saveDocument()
+ self.closeDocument()
self.docEditor.setText(self.theDocument.openDocument(tHandle))
self.docEditor.setReadOnly(False)
self.docEditor.setCursorPosition(self.theDocument.theItem.cursorPos)
@@ -303,13 +287,13 @@ class GuiMain(QMainWindow):
def saveDocument(self):
if self.theDocument.theItem is not None:
- docHtml = self.docEditor.getText()
+ docText = self.docEditor.getText()
cursPos = self.docEditor.getCursorPosition()
self.theDocument.theItem.setCharCount(self.docEditor.charCount)
self.theDocument.theItem.setWordCount(self.docEditor.wordCount)
self.theDocument.theItem.setParaCount(self.docEditor.paraCount)
self.theDocument.theItem.setCursorPos(cursPos)
- self.theDocument.saveDocument(docHtml)
+ self.theDocument.saveDocument(docText)
self.docEditor.setDocumentChanged(False)
return True
@@ -393,7 +377,9 @@ class GuiMain(QMainWindow):
dlgOpt = QFileDialog.Options()
dlgOpt |= QFileDialog.DontUseNativeDialog
projFile, _ = QFileDialog.getOpenFileName(
- self,"Open novelWriter Project","","novelWriter Project File (nwProject.nwx);;All Files (*)",options=dlgOpt
+ self, "Open novelWriter Project", "",
+ "novelWriter Project File (%s);;All Files (*)" % nwFiles.PROJ_FILE,
+ options=dlgOpt
)
if projFile:
return projFile
@@ -427,26 +413,56 @@ class GuiMain(QMainWindow):
self._setWindowTitle(self.theProject.projName)
return True
+ def makeAlert(self, theMessage, theLevel=nwAlert.INFO):
+ """Alert both the user and the logger at the same time. Message can be either a string or an
+ array of strings. Severity level is 0 = info, 1 = warning, and 2 = error.
+ """
+
+ if isinstance(theMessage, list):
+ popMsg = "
".join(theMessage)
+ logMsg = theMessage
+ else:
+ popMsg = theMessage
+ logMsg = [theMessage]
+
+ msgBox = QMessageBox()
+ if theLevel == nwAlert.INFO:
+ for msgLine in logMsg:
+ logger.info(msgLine)
+ msgBox.information(self, "Information", popMsg)
+ elif theLevel == nwAlert.WARN:
+ for msgLine in logMsg:
+ logger.warning(msgLine)
+ msgBox.warning(self, "Warning", popMsg)
+ elif theLevel == nwAlert.ERROR:
+ for msgLine in logMsg:
+ logger.error(msgLine)
+ msgBox.critical(self, "Error", popMsg)
+ elif theLevel == nwAlert.BUG:
+ for msgLine in logMsg:
+ logger.error(msgLine)
+ popMsg += "
This is a bug!"
+ msgBox.critical(self, "Internal Error", popMsg)
+
+ return
+
##
# Main Window Actions
##
- def closeMain(self, isYes=False):
+ def closeMain(self):
- if not isYes:
+ if self.mainConf.showGUI:
msgBox = QMessageBox()
msgRes = msgBox.question(
- self, "Exit",
- "Do you want to exit %s?" % nw.__package__
+ self, "Exit", "Do you want to save changes and exit?"
)
if msgRes != QMessageBox.Yes:
return False
logger.info("Exiting %s" % nw.__package__)
- if self._takeDocumentAction():
- self.saveDocument()
- if self._takeProjectAction():
- self.saveProject()
+ self.closeProject(True)
+
self.mainConf.setWinSize(self.width(), self.height())
self.mainConf.setTreeColWidths(self.treeView.getColumnSizes())
self.mainConf.setMainPanePos(self.splitMain.sizes())
@@ -466,6 +482,11 @@ class GuiMain(QMainWindow):
self.docViewer.setFocus()
return
+ def closeDocEditor(self):
+ self.closeDocument()
+ self.theProject.setLastEdited(None)
+ return
+
def closeDocViewer(self):
self.docViewer.clearViewer()
self.theProject.setLastViewed(None)
@@ -488,31 +509,17 @@ class GuiMain(QMainWindow):
return True
def _autoSaveProject(self):
- if self._takeProjectAction():
+ if self.hasProject and self.theProject.projChanged and self.theProject.projPath is not None:
logger.debug("Autosaving project")
self.saveProject()
return
def _autoSaveDocument(self):
- if self._takeDocumentAction():
+ if self.hasProject and self.docEditor.docChanged and self.theDocument.theItem is not None:
logger.debug("Autosaving document")
self.saveDocument()
return
- def _takeProjectAction(self):
- if self.theProject.projPath is None:
- return False
- if not self.theProject.projChanged:
- return False
- return True
-
- def _takeDocumentAction(self):
- if self.theDocument.theItem is None:
- return False
- if not self.docEditor.docChanged:
- return False
- return True
-
def _makeStatusIcons(self):
self.statusIcons = {}
for sLabel, sCol, _ in self.theProject.statusItems:
@@ -541,7 +548,10 @@ class GuiMain(QMainWindow):
return
def closeEvent(self, theEvent):
- self.closeMain()
+ if self.closeMain():
+ theEvent.accept()
+ else:
+ theEvent.ignore()
return
##
diff --git a/nw/project/project.py b/nw/project/project.py
index 3c2f68fa..dce45ef3 100644
--- a/nw/project/project.py
+++ b/nw/project/project.py
@@ -19,10 +19,11 @@ from hashlib import sha256
from datetime import datetime
from time import time
-from nw.enum import nwItemType, nwItemClass, nwItemLayout, nwAlert
-from nw.common import checkString, checkBool
from nw.project.item import NWItem
from nw.project.status import NWStatus
+from nw.enum import nwItemType, nwItemClass, nwItemLayout, nwAlert
+from nw.common import checkString, checkBool, checkInt
+from nw.constants import nwFiles
logger = logging.getLogger(__name__)
@@ -34,6 +35,7 @@ class NWProject():
self.theParent = theParent
self.mainConf = self.theParent.mainConf
self.projChanged = None
+ self.projOpened = None
# Debug
self.handleSeed = None
@@ -59,6 +61,8 @@ class NWProject():
self.importItems = None
self.lastEdited = None
self.lastViewed = None
+ self.lastWCount = 0
+ self.currWCount = 0
# Set Defaults
self.clearProject()
@@ -119,19 +123,20 @@ class NWProject():
##
def newProject(self):
-
hNovel = self.newRoot("Novel", nwItemClass.NOVEL)
hChars = self.newRoot("Characters", nwItemClass.CHARACTER)
hWorld = self.newRoot("Plot", nwItemClass.PLOT)
hWorld = self.newRoot("World", nwItemClass.WORLD)
hChapt = self.newFolder("New Chapter", nwItemClass.NOVEL, hNovel)
hScene = self.newFile("New Scene", nwItemClass.NOVEL, hChapt)
-
+ self.projOpened = time()
+ self.setProjectChanged(True)
return True
def clearProject(self):
self.projChanged = None
+ self.projOpened = None
# Project Settings
self.projTree = {}
@@ -141,7 +146,7 @@ class NWProject():
self.projPath = None
self.projMeta = None
self.projCache = None
- self.projFile = "nwProject.nwx"
+ self.projFile = nwFiles.PROJ_FILE
self.projName = ""
self.bookTitle = ""
self.bookAuthors = []
@@ -156,13 +161,17 @@ class NWProject():
self.importItems.addEntry("Minor", (200, 50, 0))
self.importItems.addEntry("Major", (200,150, 0))
self.importItems.addEntry("Main", ( 50,200, 0))
+ self.lastEdited = None
+ self.lastViewed = None
+ self.lastWCount = 0
+ self.currWCount = 0
return
def openProject(self, fileName):
if not path.isfile(fileName):
- fileName = path.join(fileName, "nwProject.nwx")
+ fileName = path.join(fileName, nwFiles.PROJ_FILE)
if not path.isfile(fileName):
self.makeAlert("File not found: %s" % fileName, nwAlert.ERROR)
return False
@@ -215,6 +224,8 @@ class NWProject():
self.lastEdited = checkString(xItem.text,None,True)
if xItem.tag == "lastViewed":
self.lastViewed = checkString(xItem.text,None,True)
+ if xItem.tag == "lastWordCount":
+ self.lastWCount = checkInt(xItem.text,0,False)
if xItem.tag == "status":
self.statusItems.unpackEntries(xItem)
if xItem.tag == "importance":
@@ -242,6 +253,7 @@ class NWProject():
self._scanProjectFolder()
self.setProjectChanged(False)
+ self.projOpened = time()
return True
@@ -276,9 +288,10 @@ class NWProject():
# Save Project Settings
xSettings = etree.SubElement(nwXML,"settings")
- self._saveProjectValue(xSettings,"spellCheck",self.spellCheck)
- self._saveProjectValue(xSettings,"lastEdited",self.lastEdited)
- self._saveProjectValue(xSettings,"lastViewed",self.lastViewed)
+ self._saveProjectValue(xSettings,"spellCheck", self.spellCheck)
+ self._saveProjectValue(xSettings,"lastEdited", self.lastEdited)
+ self._saveProjectValue(xSettings,"lastViewed", self.lastViewed)
+ self._saveProjectValue(xSettings,"lastWordCount",self.currWCount)
xStatus = etree.SubElement(xSettings,"status")
self.statusItems.packEntries(xStatus)
@@ -311,6 +324,11 @@ class NWProject():
return True
+ def closeProject(self):
+ self._appendSessionStats()
+ self.clearProject()
+ return True
+
##
# Set Functions
##
@@ -365,6 +383,14 @@ class NWProject():
self.setProjectChanged(True)
return True
+ def setProjectWordCount(self, theCount):
+ self.currWCount = theCount
+ self.setProjectChanged(True)
+ return True
+
+ def getSessionWordCount(self):
+ return self.currWCount - self.lastWCount
+
def setStatusColours(self, newCols):
replaceMap = self.statusItems.setNewEntries(newCols)
if self.projTree is not None:
@@ -576,6 +602,24 @@ class NWProject():
return
+ def _appendSessionStats(self):
+
+ if self.projMeta is None:
+ return False
+
+ with open(path.join(self.projMeta, nwFiles.SESS_INFO), mode="a+") as outFile:
+ print((
+ "Start: {opened:s} "
+ "End: {closed:s} "
+ "Words: {words:8d}"
+ ).format(
+ opened = datetime.fromtimestamp(self.projOpened).strftime("%Y-%m-%d %H:%M:%S"),
+ closed = datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
+ words = self.getSessionWordCount(),
+ ), file=outFile)
+
+ return True
+
def _makeHandle(self, addSeed=""):
if self.handleSeed is None:
newSeed = str(time()) + addSeed
diff --git a/sample/sampleNovel/data_6/36b6aa9b697b_main.nwd b/sample/sampleNovel/data_6/36b6aa9b697b_main.nwd
index 72d112c6..eb71a80b 100644
--- a/sample/sampleNovel/data_6/36b6aa9b697b_main.nwd
+++ b/sample/sampleNovel/data_6/36b6aa9b697b_main.nwd
@@ -13,8 +13,12 @@ Some text here would look good as well, and maybe some "dialogue"?
So, this is some __text__ that we’ve been adding to this document. It is utterly meaningless text, _but_ since this is just dummy text, that doesn’t really matter. The text is perfectly happy to live in this document regardless.
-This paragraph is also meaningless. At least a bit. It’s also very short.
+This paragraph is also meaningless. At least a bit. It’s also very short. But we could make it less meaningless if we wanted to … but we won’t, will we.
This one is a bit longer. “It also has some dialogue in it” she said, before she moved on to check if the spellchecker worked. It did. “Cool,” she concluded.
+@ToDo: Stuff that will be done at some point
+
+
+
diff --git a/sample/sampleNovel/meta/sessionInfo.log b/sample/sampleNovel/meta/sessionInfo.log
new file mode 100644
index 00000000..79d3266e
--- /dev/null
+++ b/sample/sampleNovel/meta/sessionInfo.log
@@ -0,0 +1,15 @@
+Start: 2019-05-26 14:28:28 End: 2019-05-26 14:28:38 Words: -23
+Start: 2019-05-26 14:31:12 End: 2019-05-26 14:31:34 Words: 12
+Start: 2019-05-26 14:33:27 End: 2019-05-26 14:33:31 Words: 0
+Start: 2019-05-26 14:40:29 End: 2019-05-26 14:40:32 Words: 0
+Start: 2019-05-26 14:40:43 End: 2019-05-26 14:40:46 Words: 0
+Start: 2019-05-26 14:48:40 End: 2019-05-26 14:48:50 Words: 0
+Start: 2019-05-26 14:50:18 End: 2019-05-26 14:50:21 Words: 0
+Start: 2019-05-26 14:50:29 End: 2019-05-26 14:50:47 Words: 3
+Start: 2019-05-26 15:10:52 End: 2019-05-26 15:11:09 Words: 0
+Start: 2019-05-26 15:28:56 End: 2019-05-26 15:29:08 Words: 0
+Start: 2019-05-26 15:37:34 End: 2019-05-26 15:37:43 Words: -538
+Start: 2019-05-26 15:37:47 End: 2019-05-26 15:38:07 Words: 538
+Start: 2019-05-26 15:38:11 End: 2019-05-26 15:43:07 Words: 2
+Start: 2019-05-26 15:49:18 End: 2019-05-26 15:49:47 Words: 0
+Start: 2019-05-26 15:52:39 End: 2019-05-26 15:52:56 Words: 0
diff --git a/sample/sampleNovel/nwProject.nwx b/sample/sampleNovel/nwProject.nwx
index 0a81731f..448da65a 100644
--- a/sample/sampleNovel/nwProject.nwx
+++ b/sample/sampleNovel/nwProject.nwx
@@ -1,5 +1,5 @@
-
+
Sample Project
Sample Project
@@ -9,7 +9,8 @@
True
636b6aa9b697b
- 636b6aa9b697b
+ None
+ 540
New
Notes
@@ -72,10 +73,10 @@
Notes
False
SCENE
- 577
- 104
+ 656
+ 121
5
- 603
+ 573
-
New File
diff --git a/tests/reference/gui/0_nwProject.nwx b/tests/reference/gui/0_nwProject.nwx
index a42179e9..e1685c0f 100644
--- a/tests/reference/gui/0_nwProject.nwx
+++ b/tests/reference/gui/0_nwProject.nwx
@@ -1,5 +1,5 @@
-
+
@@ -8,6 +8,7 @@
False
None
None
+ 0
New
Note
diff --git a/tests/reference/gui/1_nwProject.nwx b/tests/reference/gui/1_nwProject.nwx
index 971954a6..ae897362 100644
--- a/tests/reference/gui/1_nwProject.nwx
+++ b/tests/reference/gui/1_nwProject.nwx
@@ -1,5 +1,5 @@
-
+
@@ -8,6 +8,7 @@
True
31489056e0916
31489056e0916
+ 69
New
Note
diff --git a/tests/reference/gui/2_nwProject.nwx b/tests/reference/gui/2_nwProject.nwx
index 02f3c384..8d2ab8f5 100644
--- a/tests/reference/gui/2_nwProject.nwx
+++ b/tests/reference/gui/2_nwProject.nwx
@@ -1,5 +1,5 @@
-
+
Project Name
Project Title
@@ -10,6 +10,7 @@
False
None
None
+ 0
New
Note
diff --git a/tests/reference/gui/3_nwProject.nwx b/tests/reference/gui/3_nwProject.nwx
index 510192ff..d499a736 100644
--- a/tests/reference/gui/3_nwProject.nwx
+++ b/tests/reference/gui/3_nwProject.nwx
@@ -1,5 +1,5 @@
-
+
@@ -8,6 +8,7 @@
False
None
None
+ 0
New
Note
diff --git a/tests/reference/novelwriter.conf b/tests/reference/novelwriter.conf
index 112f9fd8..cb999b5a 100644
--- a/tests/reference/novelwriter.conf
+++ b/tests/reference/novelwriter.conf
@@ -1,5 +1,5 @@
[Main]
-timestamp = 2019-05-18 15:06:44
+timestamp = 2019-05-25 23:33:23
theme = default
[Sizes]
@@ -17,6 +17,7 @@ fixedwidth = True
width = 600
margins = 40, 40
textsize = 13
+tabwidth = 40
justify = True
autoselect = True
autoreplace = True
diff --git a/tests/reference/proj/1_nwProject.nwx b/tests/reference/proj/1_nwProject.nwx
index e9ff11f5..40ec363c 100644
--- a/tests/reference/proj/1_nwProject.nwx
+++ b/tests/reference/proj/1_nwProject.nwx
@@ -1,5 +1,5 @@
-
+
@@ -8,6 +8,7 @@
False
None
None
+ 0
New
Note
diff --git a/tests/reference/proj/2_nwProject.nwx b/tests/reference/proj/2_nwProject.nwx
index 8c68bc42..314a4f75 100644
--- a/tests/reference/proj/2_nwProject.nwx
+++ b/tests/reference/proj/2_nwProject.nwx
@@ -1,5 +1,5 @@
-
+
@@ -8,6 +8,7 @@
False
None
None
+ 0
New
Note
diff --git a/tests/test_gui.py b/tests/test_gui.py
index 94ce7eb4..7f141b47 100644
--- a/tests/test_gui.py
+++ b/tests/test_gui.py
@@ -27,7 +27,7 @@ def testMainWindows(qtbot, nwTempGUI, nwRef):
nwGUI.theProject.handleSeed = 42
assert nwGUI.newProject(nwTempGUI, True)
assert nwGUI.saveProject()
- assert nwGUI.closeProject(True)
+ assert nwGUI.closeProject()
assert len(nwGUI.theProject.projTree) == 0
assert len(nwGUI.theProject.treeOrder) == 0
@@ -155,7 +155,7 @@ def testMainWindows(qtbot, nwTempGUI, nwRef):
sceneFile = path.join(nwTempGUI,"data_3","1489056e0916_main.nwd")
assert cmpFiles(sceneFile, path.join(nwRef,"gui","1_1489056e0916_main.nwd"))
- nwGUI.closeMain(True)
+ nwGUI.closeMain()
# qtbot.stopForInteraction()
@pytest.mark.gui
@@ -217,7 +217,7 @@ def testProjectEditor(qtbot, nwTempGUI, nwRef):
projFile = path.join(nwTempGUI,"nwProject.nwx")
assert cmpFiles(projFile, path.join(nwRef,"gui","2_nwProject.nwx"), [2])
- nwGUI.closeMain(True)
+ nwGUI.closeMain()
# qtbot.stopForInteraction()
@pytest.mark.gui
@@ -263,5 +263,5 @@ def testItemEditor(qtbot, nwTempGUI, nwRef):
projFile = path.join(nwTempGUI,"nwProject.nwx")
assert cmpFiles(projFile, path.join(nwRef,"gui","3_nwProject.nwx"), [2])
- nwGUI.closeMain(True)
+ nwGUI.closeMain()
# qtbot.stopForInteraction()