@@ -102,6 +102,10 @@ class Config:
|
|||||||
self.outlnPanePos = [500, 150]
|
self.outlnPanePos = [500, 150]
|
||||||
self.isFullScreen = False
|
self.isFullScreen = False
|
||||||
|
|
||||||
|
## Features
|
||||||
|
self.hideVScroll = False # Hide vertical scroll bars on main widgets
|
||||||
|
self.hideHScroll = False # Hide horizontal scroll bars on main widgets
|
||||||
|
|
||||||
## Project
|
## Project
|
||||||
self.autoSaveProj = 60
|
self.autoSaveProj = 60
|
||||||
self.autoSaveDoc = 30
|
self.autoSaveDoc = 30
|
||||||
@@ -122,6 +126,9 @@ class Config:
|
|||||||
self.doReplaceDQuote = True
|
self.doReplaceDQuote = True
|
||||||
self.doReplaceDash = True
|
self.doReplaceDash = True
|
||||||
self.doReplaceDots = True
|
self.doReplaceDots = True
|
||||||
|
self.scrollPastEnd = True
|
||||||
|
self.scollWithCursor = False
|
||||||
|
|
||||||
self.wordCountTimer = 5.0
|
self.wordCountTimer = 5.0
|
||||||
self.showTabsNSpaces = False
|
self.showTabsNSpaces = False
|
||||||
self.showLineEndings = False
|
self.showLineEndings = False
|
||||||
@@ -391,6 +398,12 @@ class Config:
|
|||||||
self.isFullScreen = self._parseLine(
|
self.isFullScreen = self._parseLine(
|
||||||
cnfParse, cnfSec, "fullscreen", self.CNF_BOOL, self.isFullScreen
|
cnfParse, cnfSec, "fullscreen", self.CNF_BOOL, self.isFullScreen
|
||||||
)
|
)
|
||||||
|
self.hideVScroll = self._parseLine(
|
||||||
|
cnfParse, cnfSec, "hidevscroll", self.CNF_BOOL, self.hideVScroll
|
||||||
|
)
|
||||||
|
self.hideHScroll = self._parseLine(
|
||||||
|
cnfParse, cnfSec, "hidehscroll", self.CNF_BOOL, self.hideHScroll
|
||||||
|
)
|
||||||
|
|
||||||
## Project
|
## Project
|
||||||
cnfSec = "Project"
|
cnfSec = "Project"
|
||||||
@@ -448,6 +461,12 @@ class Config:
|
|||||||
self.doReplaceDots = self._parseLine(
|
self.doReplaceDots = self._parseLine(
|
||||||
cnfParse, cnfSec, "repdots", self.CNF_BOOL, self.doReplaceDots
|
cnfParse, cnfSec, "repdots", self.CNF_BOOL, self.doReplaceDots
|
||||||
)
|
)
|
||||||
|
self.scrollPastEnd = self._parseLine(
|
||||||
|
cnfParse, cnfSec, "scrollpastend", self.CNF_BOOL, self.scrollPastEnd
|
||||||
|
)
|
||||||
|
self.scollWithCursor = self._parseLine(
|
||||||
|
cnfParse, cnfSec, "scollwithcursor", self.CNF_BOOL, self.scollWithCursor
|
||||||
|
)
|
||||||
self.fmtSingleQuotes = self._parseLine(
|
self.fmtSingleQuotes = self._parseLine(
|
||||||
cnfParse, cnfSec, "fmtsinglequote", self.CNF_LIST, self.fmtSingleQuotes
|
cnfParse, cnfSec, "fmtsinglequote", self.CNF_LIST, self.fmtSingleQuotes
|
||||||
)
|
)
|
||||||
@@ -565,6 +584,8 @@ class Config:
|
|||||||
cnfParse.set(cnfSec, "viewpane", self._packList(self.viewPanePos))
|
cnfParse.set(cnfSec, "viewpane", self._packList(self.viewPanePos))
|
||||||
cnfParse.set(cnfSec, "outlinepane", self._packList(self.outlnPanePos))
|
cnfParse.set(cnfSec, "outlinepane", self._packList(self.outlnPanePos))
|
||||||
cnfParse.set(cnfSec, "fullscreen", str(self.isFullScreen))
|
cnfParse.set(cnfSec, "fullscreen", str(self.isFullScreen))
|
||||||
|
cnfParse.set(cnfSec, "hidevscroll", str(self.hideVScroll))
|
||||||
|
cnfParse.set(cnfSec, "hidehscroll", str(self.hideHScroll))
|
||||||
|
|
||||||
## Project
|
## Project
|
||||||
cnfSec = "Project"
|
cnfSec = "Project"
|
||||||
@@ -590,6 +611,8 @@ class Config:
|
|||||||
cnfParse.set(cnfSec, "repdquotes", str(self.doReplaceDQuote))
|
cnfParse.set(cnfSec, "repdquotes", str(self.doReplaceDQuote))
|
||||||
cnfParse.set(cnfSec, "repdash", str(self.doReplaceDash))
|
cnfParse.set(cnfSec, "repdash", str(self.doReplaceDash))
|
||||||
cnfParse.set(cnfSec, "repdots", str(self.doReplaceDots))
|
cnfParse.set(cnfSec, "repdots", str(self.doReplaceDots))
|
||||||
|
cnfParse.set(cnfSec, "scrollpastend", str(self.scrollPastEnd))
|
||||||
|
cnfParse.set(cnfSec, "scollwithcursor", str(self.scollWithCursor))
|
||||||
cnfParse.set(cnfSec, "fmtsinglequote", self._packList(self.fmtSingleQuotes))
|
cnfParse.set(cnfSec, "fmtsinglequote", self._packList(self.fmtSingleQuotes))
|
||||||
cnfParse.set(cnfSec, "fmtdoublequote", self._packList(self.fmtDoubleQuotes))
|
cnfParse.set(cnfSec, "fmtdoublequote", self._packList(self.fmtDoubleQuotes))
|
||||||
cnfParse.set(cnfSec, "spelltool", str(self.spellTool))
|
cnfParse.set(cnfSec, "spelltool", str(self.spellTool))
|
||||||
|
|||||||
+21
-2
@@ -450,11 +450,19 @@ class GuiBuildNovel(QDialog):
|
|||||||
# Tool Box Scroll Area
|
# Tool Box Scroll Area
|
||||||
self.toolsArea = QScrollArea()
|
self.toolsArea = QScrollArea()
|
||||||
self.toolsArea.setMinimumWidth(self.mainConf.pxInt(250))
|
self.toolsArea.setMinimumWidth(self.mainConf.pxInt(250))
|
||||||
self.toolsArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
|
||||||
self.toolsArea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
|
||||||
self.toolsArea.setWidgetResizable(True)
|
self.toolsArea.setWidgetResizable(True)
|
||||||
self.toolsArea.setWidget(self.toolsWidget)
|
self.toolsArea.setWidget(self.toolsWidget)
|
||||||
|
|
||||||
|
if self.mainConf.hideVScroll:
|
||||||
|
self.toolsArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||||
|
else:
|
||||||
|
self.toolsArea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
||||||
|
|
||||||
|
if self.mainConf.hideHScroll:
|
||||||
|
self.toolsArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||||
|
else:
|
||||||
|
self.toolsArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
||||||
|
|
||||||
# Tools and Buttons Layout
|
# Tools and Buttons Layout
|
||||||
self.innerBox = QVBoxLayout()
|
self.innerBox = QVBoxLayout()
|
||||||
self.innerBox.addWidget(self.toolsArea)
|
self.innerBox.addWidget(self.toolsArea)
|
||||||
@@ -1116,6 +1124,17 @@ class GuiBuildNovelDocView(QTextBrowser):
|
|||||||
else:
|
else:
|
||||||
self.setTabStopWidth(self.mainConf.getTabWidth())
|
self.setTabStopWidth(self.mainConf.getTabWidth())
|
||||||
|
|
||||||
|
# Scroll bars
|
||||||
|
if self.mainConf.hideVScroll:
|
||||||
|
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||||
|
else:
|
||||||
|
self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
||||||
|
|
||||||
|
if self.mainConf.hideHScroll:
|
||||||
|
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||||
|
else:
|
||||||
|
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
||||||
|
|
||||||
docPalette = self.palette()
|
docPalette = self.palette()
|
||||||
docPalette.setColor(QPalette.Base, QColor(255, 255, 255))
|
docPalette.setColor(QPalette.Base, QColor(255, 255, 255))
|
||||||
docPalette.setColor(QPalette.Text, QColor(0, 0, 0))
|
docPalette.setColor(QPalette.Text, QColor(0, 0, 0))
|
||||||
|
|||||||
+66
-2
@@ -88,6 +88,8 @@ class GuiDocEditor(QTextEdit):
|
|||||||
self.bigDoc = False # Flag for very large document size
|
self.bigDoc = False # Flag for very large document size
|
||||||
self.doReplace = False # Switch to temporarily disable auto-replace
|
self.doReplace = False # Switch to temporarily disable auto-replace
|
||||||
self.queuePos = None # Used for delayed change of cursor position
|
self.queuePos = None # Used for delayed change of cursor position
|
||||||
|
self.cursorLast = 0 # The last known vertical position of the cursor
|
||||||
|
self.lengthLast = 0
|
||||||
|
|
||||||
# Typography
|
# Typography
|
||||||
self.typDQOpen = self.mainConf.fmtDoubleQuotes[0]
|
self.typDQOpen = self.mainConf.fmtDoubleQuotes[0]
|
||||||
@@ -100,6 +102,8 @@ class GuiDocEditor(QTextEdit):
|
|||||||
self.qDocument.contentsChange.connect(self._docChange)
|
self.qDocument.contentsChange.connect(self._docChange)
|
||||||
self.qDocument.documentLayout().documentSizeChanged.connect(self._docSizeChanged)
|
self.qDocument.documentLayout().documentSizeChanged.connect(self._docSizeChanged)
|
||||||
|
|
||||||
|
self.verticalScrollBar().sliderMoved.connect(self._doVerticalScroll)
|
||||||
|
|
||||||
# Document Title
|
# Document Title
|
||||||
self.docHeader = GuiDocEditHeader(self)
|
self.docHeader = GuiDocEditHeader(self)
|
||||||
self.docFooter = GuiDocEditFooter(self)
|
self.docFooter = GuiDocEditFooter(self)
|
||||||
@@ -224,6 +228,17 @@ class GuiDocEditor(QTextEdit):
|
|||||||
|
|
||||||
self.qDocument.setDefaultTextOption(theOpt)
|
self.qDocument.setDefaultTextOption(theOpt)
|
||||||
|
|
||||||
|
# Scroll bars
|
||||||
|
if self.mainConf.hideVScroll:
|
||||||
|
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||||
|
else:
|
||||||
|
self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
||||||
|
|
||||||
|
if self.mainConf.hideHScroll:
|
||||||
|
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||||
|
else:
|
||||||
|
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
||||||
|
|
||||||
# Refresh the tab stops
|
# Refresh the tab stops
|
||||||
if self.mainConf.verQtValue >= 51000:
|
if self.mainConf.verQtValue >= 51000:
|
||||||
self.setTabStopDistance(self.mainConf.getTabWidth())
|
self.setTabStopDistance(self.mainConf.getTabWidth())
|
||||||
@@ -313,6 +328,7 @@ class GuiDocEditor(QTextEdit):
|
|||||||
self.setCursorLine(tLine)
|
self.setCursorLine(tLine)
|
||||||
|
|
||||||
self.docFooter.updateLineCount()
|
self.docFooter.updateLineCount()
|
||||||
|
self.lengthLast = self.qDocument.characterCount()
|
||||||
|
|
||||||
qApp.restoreOverrideCursor()
|
qApp.restoreOverrideCursor()
|
||||||
|
|
||||||
@@ -360,9 +376,14 @@ class GuiDocEditor(QTextEdit):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
docText = self.getText()
|
docText = self.getText()
|
||||||
|
|
||||||
|
cC, wC, pC = countWords(docText)
|
||||||
|
self._updateCounts(cC, wC, pC)
|
||||||
|
|
||||||
theItem.setCharCount(self.charCount)
|
theItem.setCharCount(self.charCount)
|
||||||
theItem.setWordCount(self.wordCount)
|
theItem.setWordCount(self.wordCount)
|
||||||
theItem.setParaCount(self.paraCount)
|
theItem.setParaCount(self.paraCount)
|
||||||
|
|
||||||
self.saveCursorPosition()
|
self.saveCursorPosition()
|
||||||
self.nwDocument.saveDocument(docText)
|
self.nwDocument.saveDocument(docText)
|
||||||
self.setDocumentChanged(False)
|
self.setDocumentChanged(False)
|
||||||
@@ -377,6 +398,7 @@ class GuiDocEditor(QTextEdit):
|
|||||||
just ensure the margins are set correctly.
|
just ensure the margins are set correctly.
|
||||||
"""
|
"""
|
||||||
wW = self.width()
|
wW = self.width()
|
||||||
|
wH = self.height()
|
||||||
cM = self.mainConf.getTextMargin()
|
cM = self.mainConf.getTextMargin()
|
||||||
|
|
||||||
vBar = self.verticalScrollBar()
|
vBar = self.verticalScrollBar()
|
||||||
@@ -400,7 +422,7 @@ class GuiDocEditor(QTextEdit):
|
|||||||
tW = wW - 2*tB - sW
|
tW = wW - 2*tB - sW
|
||||||
tH = self.docHeader.height()
|
tH = self.docHeader.height()
|
||||||
fH = self.docFooter.height()
|
fH = self.docFooter.height()
|
||||||
fY = self.height() - fH - tB - sH
|
fY = wH - fH - tB - sH
|
||||||
self.docHeader.setGeometry(tB, tB, tW, tH)
|
self.docHeader.setGeometry(tB, tB, tW, tH)
|
||||||
self.docFooter.setGeometry(tB, fY, tW, fH)
|
self.docFooter.setGeometry(tB, fY, tW, fH)
|
||||||
|
|
||||||
@@ -412,7 +434,14 @@ class GuiDocEditor(QTextEdit):
|
|||||||
else:
|
else:
|
||||||
rH = 0
|
rH = 0
|
||||||
|
|
||||||
self.setViewportMargins(tM, max(cM, tH, rH), tM, max(cM, fH))
|
uM = max(cM, tH, rH)
|
||||||
|
lM = max(cM, fH)
|
||||||
|
self.setViewportMargins(tM, uM, tM, lM)
|
||||||
|
|
||||||
|
if self.mainConf.scrollPastEnd:
|
||||||
|
docFrame = self.qDocument.rootFrame().frameFormat()
|
||||||
|
docFrame.setBottomMargin(wH - uM - lM - 4*tB - self.theTheme.fontPixelSize)
|
||||||
|
self.qDocument.rootFrame().setFrameFormat(docFrame)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -460,11 +489,14 @@ class GuiDocEditor(QTextEdit):
|
|||||||
"""
|
"""
|
||||||
if not isinstance(thePosition, int):
|
if not isinstance(thePosition, int):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if thePosition >= 0:
|
if thePosition >= 0:
|
||||||
theCursor = self.textCursor()
|
theCursor = self.textCursor()
|
||||||
theCursor.setPosition(thePosition)
|
theCursor.setPosition(thePosition)
|
||||||
self.setTextCursor(theCursor)
|
self.setTextCursor(theCursor)
|
||||||
self.docFooter.updateLineCount()
|
self.docFooter.updateLineCount()
|
||||||
|
self.cursorLast = self.cursorRect().center().y()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def getCursorPosition(self):
|
def getCursorPosition(self):
|
||||||
@@ -743,6 +775,22 @@ class GuiDocEditor(QTextEdit):
|
|||||||
QTextEdit.keyPressEvent(self, keyEvent)
|
QTextEdit.keyPressEvent(self, keyEvent)
|
||||||
self.docFooter.updateLineCount()
|
self.docFooter.updateLineCount()
|
||||||
|
|
||||||
|
if self.mainConf.scollWithCursor:
|
||||||
|
docLen = self.qDocument.characterCount()
|
||||||
|
if docLen == self.lengthLast:
|
||||||
|
# No change, so just update last position
|
||||||
|
self.cursorLast = self.cursorRect().center().y()
|
||||||
|
else:
|
||||||
|
# The user typed something, so check if we need to
|
||||||
|
# scroll, and move the scroll bar the same distance
|
||||||
|
self.lengthLast = docLen
|
||||||
|
self.ensureCursorVisible()
|
||||||
|
cPos = self.cursorRect().center().y()
|
||||||
|
if cPos != self.cursorLast:
|
||||||
|
vBar = self.verticalScrollBar()
|
||||||
|
vBar.setValue(vBar.value() + cPos - self.cursorLast)
|
||||||
|
self.cursorLast = self.cursorRect().center().y()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def focusNextPrevChild(self, toNext):
|
def focusNextPrevChild(self, toNext):
|
||||||
@@ -768,9 +816,18 @@ class GuiDocEditor(QTextEdit):
|
|||||||
|
|
||||||
QTextEdit.mouseReleaseEvent(self, mEvent)
|
QTextEdit.mouseReleaseEvent(self, mEvent)
|
||||||
self.docFooter.updateLineCount()
|
self.docFooter.updateLineCount()
|
||||||
|
self.cursorLast = self.cursorRect().center().y()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def wheelEvent(self, theEvent):
|
||||||
|
"""Briefly capture the mouse wheel event to capture the cursor
|
||||||
|
position.
|
||||||
|
"""
|
||||||
|
QTextEdit.wheelEvent(self, theEvent)
|
||||||
|
self.cursorLast = self.cursorRect().center().y()
|
||||||
|
return
|
||||||
|
|
||||||
def resizeEvent(self, theEvent):
|
def resizeEvent(self, theEvent):
|
||||||
"""If the text editor is resize, we must make sure the document
|
"""If the text editor is resize, we must make sure the document
|
||||||
has its margins adjusted according to user preferences.
|
has its margins adjusted according to user preferences.
|
||||||
@@ -805,6 +862,13 @@ class GuiDocEditor(QTextEdit):
|
|||||||
self._docAutoReplace(self.qDocument.findBlock(thePos))
|
self._docAutoReplace(self.qDocument.findBlock(thePos))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@pyqtSlot(int)
|
||||||
|
def _doVerticalScroll(self, theChange):
|
||||||
|
"""Update the cursor position on vertical scrolling.
|
||||||
|
"""
|
||||||
|
self.cursorLast = self.cursorRect().center().y()
|
||||||
|
return
|
||||||
|
|
||||||
@pyqtSlot("QPoint")
|
@pyqtSlot("QPoint")
|
||||||
def _openContextMenu(self, thePos):
|
def _openContextMenu(self, thePos):
|
||||||
"""Triggered by right click to open the context menu. Also
|
"""Triggered by right click to open the context menu. Also
|
||||||
|
|||||||
@@ -124,6 +124,17 @@ class GuiDocViewer(QTextBrowser):
|
|||||||
theOpt.setAlignment(Qt.AlignJustify)
|
theOpt.setAlignment(Qt.AlignJustify)
|
||||||
self.qDocument.setDefaultTextOption(theOpt)
|
self.qDocument.setDefaultTextOption(theOpt)
|
||||||
|
|
||||||
|
# Scroll bars
|
||||||
|
if self.mainConf.hideVScroll:
|
||||||
|
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||||
|
else:
|
||||||
|
self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
||||||
|
|
||||||
|
if self.mainConf.hideHScroll:
|
||||||
|
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||||
|
else:
|
||||||
|
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
||||||
|
|
||||||
# Refresh the tab stops
|
# Refresh the tab stops
|
||||||
if self.mainConf.verQtValue >= 51000:
|
if self.mainConf.verQtValue >= 51000:
|
||||||
self.setTabStopDistance(self.mainConf.getTabWidth())
|
self.setTabStopDistance(self.mainConf.getTabWidth())
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ class GuiOutline(QTreeWidget):
|
|||||||
self.colIndex = {}
|
self.colIndex = {}
|
||||||
self.treeNCols = 0
|
self.treeNCols = 0
|
||||||
|
|
||||||
|
self.initOutline()
|
||||||
self.clearOutline()
|
self.clearOutline()
|
||||||
self.headerMenu.setHiddenState(self.colHidden)
|
self.headerMenu.setHiddenState(self.colHidden)
|
||||||
|
|
||||||
@@ -125,6 +126,22 @@ class GuiOutline(QTreeWidget):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def initOutline(self):
|
||||||
|
"""Set or update outline settings.
|
||||||
|
"""
|
||||||
|
# Scroll bars
|
||||||
|
if self.mainConf.hideVScroll:
|
||||||
|
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||||
|
else:
|
||||||
|
self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
||||||
|
|
||||||
|
if self.mainConf.hideHScroll:
|
||||||
|
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||||
|
else:
|
||||||
|
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
def clearOutline(self):
|
def clearOutline(self):
|
||||||
"""Clear the tree and header and set the default values for the
|
"""Clear the tree and header and set the default values for the
|
||||||
columns arrays.
|
columns arrays.
|
||||||
|
|||||||
@@ -224,10 +224,28 @@ class GuiOutlineDetails(QScrollArea):
|
|||||||
self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
||||||
self.setWidgetResizable(True)
|
self.setWidgetResizable(True)
|
||||||
|
|
||||||
|
self.initDetails()
|
||||||
|
|
||||||
logger.debug("GuiOutlineDetails initialisation complete")
|
logger.debug("GuiOutlineDetails initialisation complete")
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def initDetails(self):
|
||||||
|
"""Set or update outline settings.
|
||||||
|
"""
|
||||||
|
# Scroll bars
|
||||||
|
if self.mainConf.hideVScroll:
|
||||||
|
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||||
|
else:
|
||||||
|
self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
||||||
|
|
||||||
|
if self.mainConf.hideHScroll:
|
||||||
|
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||||
|
else:
|
||||||
|
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
def showItem(self, tHandle, sTitle):
|
def showItem(self, tHandle, sTitle):
|
||||||
"""Update the content of the tree with the given handle and line
|
"""Update the content of the tree with the given handle and line
|
||||||
number pointing to a header.
|
number pointing to a header.
|
||||||
|
|||||||
+123
-40
@@ -55,15 +55,17 @@ class GuiPreferences(PagedDialog):
|
|||||||
|
|
||||||
self.setWindowTitle("Preferences")
|
self.setWindowTitle("Preferences")
|
||||||
|
|
||||||
self.tabGeneral = GuiConfigEditGeneralTab(self.theParent)
|
self.tabGeneral = GuiConfigEditGeneralTab(self.theParent)
|
||||||
self.tabLayout = GuiConfigEditLayoutTab(self.theParent)
|
self.tabProjects = GuiConfigEditProjectsTab(self.theParent)
|
||||||
self.tabEditing = GuiConfigEditEditingTab(self.theParent)
|
self.tabLayout = GuiConfigEditLayoutTab(self.theParent)
|
||||||
self.tabAutoRep = GuiConfigEditAutoReplaceTab(self.theParent)
|
self.tabEditing = GuiConfigEditEditingTab(self.theParent)
|
||||||
|
self.tabAutoRep = GuiConfigEditAutoReplaceTab(self.theParent)
|
||||||
|
|
||||||
self.addTab(self.tabGeneral, "General")
|
self.addTab(self.tabGeneral, "General")
|
||||||
self.addTab(self.tabLayout, "Text Layout")
|
self.addTab(self.tabProjects, "Projects")
|
||||||
self.addTab(self.tabEditing, "Editor")
|
self.addTab(self.tabLayout, "Text Layout")
|
||||||
self.addTab(self.tabAutoRep, "Auto-Replace")
|
self.addTab(self.tabEditing, "Editor")
|
||||||
|
self.addTab(self.tabAutoRep, "Auto-Replace")
|
||||||
|
|
||||||
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
||||||
self.buttonBox.accepted.connect(self._doSave)
|
self.buttonBox.accepted.connect(self._doSave)
|
||||||
@@ -91,6 +93,10 @@ class GuiPreferences(PagedDialog):
|
|||||||
validEntries &= retA
|
validEntries &= retA
|
||||||
needsRestart |= retB
|
needsRestart |= retB
|
||||||
|
|
||||||
|
retA, retB = self.tabProjects.saveValues()
|
||||||
|
validEntries &= retA
|
||||||
|
needsRestart |= retB
|
||||||
|
|
||||||
retA, retB = self.tabLayout.saveValues()
|
retA, retB = self.tabLayout.saveValues()
|
||||||
validEntries &= retA
|
validEntries &= retA
|
||||||
needsRestart |= retB
|
needsRestart |= retB
|
||||||
@@ -219,9 +225,94 @@ class GuiConfigEditGeneralTab(QWidget):
|
|||||||
self.showFullPath.setChecked(self.mainConf.showFullPath)
|
self.showFullPath.setChecked(self.mainConf.showFullPath)
|
||||||
self.mainForm.addRow(
|
self.mainForm.addRow(
|
||||||
"Show full path in document header",
|
"Show full path in document header",
|
||||||
self.showFullPath
|
self.showFullPath,
|
||||||
|
"Shows the document title and parent folder names."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.hideVScroll = QSwitch()
|
||||||
|
self.hideVScroll.setChecked(self.mainConf.hideVScroll)
|
||||||
|
self.mainForm.addRow(
|
||||||
|
"Hide vertical scroll bars in main windows",
|
||||||
|
self.hideVScroll,
|
||||||
|
"Scrolling with mouse wheel and keys only."
|
||||||
|
)
|
||||||
|
|
||||||
|
self.hideHScroll = QSwitch()
|
||||||
|
self.hideHScroll.setChecked(self.mainConf.hideHScroll)
|
||||||
|
self.mainForm.addRow(
|
||||||
|
"Hide horizontal scroll bars in main windows",
|
||||||
|
self.hideHScroll,
|
||||||
|
"Scrolling with mouse wheel and keys only."
|
||||||
|
)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def saveValues(self):
|
||||||
|
"""Save the values set for this tab.
|
||||||
|
"""
|
||||||
|
validEntries = True
|
||||||
|
needsRestart = False
|
||||||
|
|
||||||
|
guiTheme = self.selectTheme.currentData()
|
||||||
|
guiIcons = self.selectIcons.currentData()
|
||||||
|
guiDark = self.preferDarkIcons.isChecked()
|
||||||
|
guiFont = self.guiFont.text()
|
||||||
|
guiFontSize = self.guiFontSize.value()
|
||||||
|
showFullPath = self.showFullPath.isChecked()
|
||||||
|
hideVScroll = self.hideVScroll.isChecked()
|
||||||
|
hideHScroll = self.hideHScroll.isChecked()
|
||||||
|
|
||||||
|
# Check if restart is needed
|
||||||
|
needsRestart |= self.mainConf.guiTheme != guiTheme
|
||||||
|
needsRestart |= self.mainConf.guiIcons != guiIcons
|
||||||
|
needsRestart |= self.mainConf.guiFont != guiFont
|
||||||
|
needsRestart |= self.mainConf.guiFontSize != guiFontSize
|
||||||
|
|
||||||
|
self.mainConf.guiTheme = guiTheme
|
||||||
|
self.mainConf.guiIcons = guiIcons
|
||||||
|
self.mainConf.guiDark = guiDark
|
||||||
|
self.mainConf.guiFont = guiFont
|
||||||
|
self.mainConf.guiFontSize = guiFontSize
|
||||||
|
self.mainConf.showFullPath = showFullPath
|
||||||
|
self.mainConf.hideVScroll = hideVScroll
|
||||||
|
self.mainConf.hideHScroll = hideHScroll
|
||||||
|
|
||||||
|
self.mainConf.confChanged = True
|
||||||
|
|
||||||
|
return validEntries, needsRestart
|
||||||
|
|
||||||
|
##
|
||||||
|
# Slots
|
||||||
|
##
|
||||||
|
|
||||||
|
def _selectFont(self):
|
||||||
|
"""Open the QFontDialog and set a font for the font style.
|
||||||
|
"""
|
||||||
|
currFont = QFont()
|
||||||
|
currFont.setFamily(self.mainConf.guiFont)
|
||||||
|
currFont.setPointSize(self.mainConf.guiFontSize)
|
||||||
|
theFont, theStatus = QFontDialog.getFont(currFont, self)
|
||||||
|
if theStatus:
|
||||||
|
self.guiFont.setText(theFont.family())
|
||||||
|
self.guiFontSize.setValue(theFont.pointSize())
|
||||||
|
return
|
||||||
|
|
||||||
|
# END Class GuiConfigEditGeneralTab
|
||||||
|
|
||||||
|
class GuiConfigEditProjectsTab(QWidget):
|
||||||
|
|
||||||
|
def __init__(self, theParent):
|
||||||
|
QWidget.__init__(self, theParent)
|
||||||
|
|
||||||
|
self.mainConf = nw.CONFIG
|
||||||
|
self.theParent = theParent
|
||||||
|
self.theTheme = theParent.theTheme
|
||||||
|
|
||||||
|
# The Form
|
||||||
|
self.mainForm = QConfigLayout()
|
||||||
|
self.mainForm.setHelpTextStyle(self.theTheme.helpText)
|
||||||
|
self.setLayout(self.mainForm)
|
||||||
|
|
||||||
# AutoSave Settings
|
# AutoSave Settings
|
||||||
# =================
|
# =================
|
||||||
self.mainForm.addGroupLabel("Automatic Save")
|
self.mainForm.addGroupLabel("Automatic Save")
|
||||||
@@ -292,30 +383,12 @@ class GuiConfigEditGeneralTab(QWidget):
|
|||||||
validEntries = True
|
validEntries = True
|
||||||
needsRestart = False
|
needsRestart = False
|
||||||
|
|
||||||
guiTheme = self.selectTheme.currentData()
|
|
||||||
guiIcons = self.selectIcons.currentData()
|
|
||||||
guiDark = self.preferDarkIcons.isChecked()
|
|
||||||
guiFont = self.guiFont.text()
|
|
||||||
guiFontSize = self.guiFontSize.value()
|
|
||||||
showFullPath = self.showFullPath.isChecked()
|
|
||||||
autoSaveDoc = self.autoSaveDoc.value()
|
autoSaveDoc = self.autoSaveDoc.value()
|
||||||
autoSaveProj = self.autoSaveProj.value()
|
autoSaveProj = self.autoSaveProj.value()
|
||||||
backupPath = self.backupPath
|
backupPath = self.backupPath
|
||||||
backupOnClose = self.backupOnClose.isChecked()
|
backupOnClose = self.backupOnClose.isChecked()
|
||||||
askBeforeBackup = self.askBeforeBackup.isChecked()
|
askBeforeBackup = self.askBeforeBackup.isChecked()
|
||||||
|
|
||||||
# Check if restart is needed
|
|
||||||
needsRestart |= self.mainConf.guiTheme != guiTheme
|
|
||||||
needsRestart |= self.mainConf.guiIcons != guiIcons
|
|
||||||
needsRestart |= self.mainConf.guiFont != guiFont
|
|
||||||
needsRestart |= self.mainConf.guiFontSize != guiFontSize
|
|
||||||
|
|
||||||
self.mainConf.guiTheme = guiTheme
|
|
||||||
self.mainConf.guiIcons = guiIcons
|
|
||||||
self.mainConf.guiDark = guiDark
|
|
||||||
self.mainConf.guiFont = guiFont
|
|
||||||
self.mainConf.guiFontSize = guiFontSize
|
|
||||||
self.mainConf.showFullPath = showFullPath
|
|
||||||
self.mainConf.autoSaveDoc = autoSaveDoc
|
self.mainConf.autoSaveDoc = autoSaveDoc
|
||||||
self.mainConf.autoSaveProj = autoSaveProj
|
self.mainConf.autoSaveProj = autoSaveProj
|
||||||
self.mainConf.backupPath = backupPath
|
self.mainConf.backupPath = backupPath
|
||||||
@@ -357,19 +430,7 @@ class GuiConfigEditGeneralTab(QWidget):
|
|||||||
self.askBeforeBackup.setEnabled(theState)
|
self.askBeforeBackup.setEnabled(theState)
|
||||||
return
|
return
|
||||||
|
|
||||||
def _selectFont(self):
|
# END Class GuiConfigEditProjectsTab
|
||||||
"""Open the QFontDialog and set a font for the font style.
|
|
||||||
"""
|
|
||||||
currFont = QFont()
|
|
||||||
currFont.setFamily(self.mainConf.guiFont)
|
|
||||||
currFont.setPointSize(self.mainConf.guiFontSize)
|
|
||||||
theFont, theStatus = QFontDialog.getFont(currFont, self)
|
|
||||||
if theStatus:
|
|
||||||
self.guiFont.setText(theFont.family())
|
|
||||||
self.guiFontSize.setValue(theFont.pointSize())
|
|
||||||
return
|
|
||||||
|
|
||||||
# END Class GuiConfigEditGeneralTab
|
|
||||||
|
|
||||||
class GuiConfigEditLayoutTab(QWidget):
|
class GuiConfigEditLayoutTab(QWidget):
|
||||||
|
|
||||||
@@ -494,6 +555,24 @@ class GuiConfigEditLayoutTab(QWidget):
|
|||||||
theUnit="px"
|
theUnit="px"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
## Scroll Past End
|
||||||
|
self.scrollPastEnd = QSwitch()
|
||||||
|
self.scrollPastEnd.setChecked(self.mainConf.scrollPastEnd)
|
||||||
|
self.mainForm.addRow(
|
||||||
|
"Scroll past end of the document",
|
||||||
|
self.scrollPastEnd,
|
||||||
|
"Allows scrolling until last line is at the top."
|
||||||
|
)
|
||||||
|
|
||||||
|
## Typewriter Scrolling
|
||||||
|
self.scollWithCursor = QSwitch()
|
||||||
|
self.scollWithCursor.setChecked(self.mainConf.scollWithCursor)
|
||||||
|
self.mainForm.addRow(
|
||||||
|
"Typewriter style scrolling",
|
||||||
|
self.scollWithCursor,
|
||||||
|
"Scrolls up when the cursor moves to a new line."
|
||||||
|
)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def saveValues(self):
|
def saveValues(self):
|
||||||
@@ -511,6 +590,8 @@ class GuiConfigEditLayoutTab(QWidget):
|
|||||||
doJustify = self.textJustify.isChecked()
|
doJustify = self.textJustify.isChecked()
|
||||||
textMargin = self.textMargin.value()
|
textMargin = self.textMargin.value()
|
||||||
tabWidth = self.tabWidth.value()
|
tabWidth = self.tabWidth.value()
|
||||||
|
scrollPastEnd = self.scrollPastEnd.isChecked()
|
||||||
|
scollWithCursor = self.scollWithCursor.isChecked()
|
||||||
|
|
||||||
self.mainConf.textFont = textFont
|
self.mainConf.textFont = textFont
|
||||||
self.mainConf.textSize = textSize
|
self.mainConf.textSize = textSize
|
||||||
@@ -521,6 +602,8 @@ class GuiConfigEditLayoutTab(QWidget):
|
|||||||
self.mainConf.doJustify = doJustify
|
self.mainConf.doJustify = doJustify
|
||||||
self.mainConf.textMargin = textMargin
|
self.mainConf.textMargin = textMargin
|
||||||
self.mainConf.tabWidth = tabWidth
|
self.mainConf.tabWidth = tabWidth
|
||||||
|
self.mainConf.scrollPastEnd = scrollPastEnd
|
||||||
|
self.mainConf.scollWithCursor = scollWithCursor
|
||||||
|
|
||||||
self.mainConf.confChanged = True
|
self.mainConf.confChanged = True
|
||||||
|
|
||||||
|
|||||||
+21
-1
@@ -115,6 +115,9 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
# The last column should just auto-scale
|
# The last column should just auto-scale
|
||||||
self.resizeColumnToContents(self.C_FLAGS)
|
self.resizeColumnToContents(self.C_FLAGS)
|
||||||
|
|
||||||
|
# Set custom settings
|
||||||
|
self.initTree()
|
||||||
|
|
||||||
logger.debug("GuiProjectTree initialisation complete")
|
logger.debug("GuiProjectTree initialisation complete")
|
||||||
|
|
||||||
# Internal Mapping
|
# Internal Mapping
|
||||||
@@ -122,6 +125,22 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def initTree(self):
|
||||||
|
"""Set or update tree widget settings.
|
||||||
|
"""
|
||||||
|
# Scroll bars
|
||||||
|
if self.mainConf.hideVScroll:
|
||||||
|
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||||
|
else:
|
||||||
|
self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
||||||
|
|
||||||
|
if self.mainConf.hideHScroll:
|
||||||
|
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||||
|
else:
|
||||||
|
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
##
|
##
|
||||||
# Class Methods
|
# Class Methods
|
||||||
##
|
##
|
||||||
@@ -241,7 +260,8 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
# Add the new item to the tree
|
# Add the new item to the tree
|
||||||
if tHandle is not None:
|
if tHandle is not None:
|
||||||
self.revealNewTreeItem(tHandle, nHandle)
|
self.revealNewTreeItem(tHandle, nHandle)
|
||||||
self.theParent.editItem(tHandle)
|
if self.mainConf.showGUI:
|
||||||
|
self.theParent.editItem(tHandle)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -790,6 +790,9 @@ class GuiMain(QMainWindow):
|
|||||||
self.saveDocument()
|
self.saveDocument()
|
||||||
self.docEditor.initEditor()
|
self.docEditor.initEditor()
|
||||||
self.docViewer.initViewer()
|
self.docViewer.initViewer()
|
||||||
|
self.treeView.initTree()
|
||||||
|
self.projView.initOutline()
|
||||||
|
self.projMeta.initDetails()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[Main]
|
[Main]
|
||||||
timestamp = 2020-06-29 17:34:15
|
timestamp = 2020-10-11 18:29:34
|
||||||
theme = default
|
theme = default
|
||||||
syntax = default_light
|
syntax = default_light
|
||||||
icons = typicons_colour_light
|
icons = typicons_colour_light
|
||||||
@@ -16,6 +16,8 @@ docpane = 400, 400
|
|||||||
viewpane = 500, 150
|
viewpane = 500, 150
|
||||||
outlinepane = 500, 150
|
outlinepane = 500, 150
|
||||||
fullscreen = False
|
fullscreen = False
|
||||||
|
hidevscroll = False
|
||||||
|
hidehscroll = False
|
||||||
|
|
||||||
[Project]
|
[Project]
|
||||||
autosaveproject = 60
|
autosaveproject = 60
|
||||||
@@ -37,6 +39,8 @@ repsquotes = True
|
|||||||
repdquotes = True
|
repdquotes = True
|
||||||
repdash = True
|
repdash = True
|
||||||
repdots = True
|
repdots = True
|
||||||
|
scrollpastend = True
|
||||||
|
scollwithcursor = False
|
||||||
fmtsinglequote = ‘, ’
|
fmtsinglequote = ‘, ’
|
||||||
fmtdoublequote = “, ”
|
fmtdoublequote = “, ”
|
||||||
spelltool = internal
|
spelltool = internal
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ docpane = 400, 400
|
|||||||
viewpane = 500, 150
|
viewpane = 500, 150
|
||||||
outlinepane = 500, 150
|
outlinepane = 500, 150
|
||||||
fullscreen = False
|
fullscreen = False
|
||||||
|
hidevscroll = True
|
||||||
|
hidehscroll = True
|
||||||
|
|
||||||
[Project]
|
[Project]
|
||||||
autosaveproject = 40
|
autosaveproject = 40
|
||||||
@@ -37,6 +39,8 @@ repsquotes = True
|
|||||||
repdquotes = True
|
repdquotes = True
|
||||||
repdash = True
|
repdash = True
|
||||||
repdots = True
|
repdots = True
|
||||||
|
scrollpastend = False
|
||||||
|
scollwithcursor = True
|
||||||
fmtsinglequote = ‘, ’
|
fmtsinglequote = ‘, ’
|
||||||
fmtdoublequote = “, ”
|
fmtdoublequote = “, ”
|
||||||
spelltool = internal
|
spelltool = internal
|
||||||
|
|||||||
+73
-69
@@ -23,7 +23,7 @@ from nw.gui import (
|
|||||||
GuiProjectLoad, GuiPreferences
|
GuiProjectLoad, GuiPreferences
|
||||||
)
|
)
|
||||||
from nw.gui.custom import QuotesDialog
|
from nw.gui.custom import QuotesDialog
|
||||||
from nw.constants import nwItemType, nwItemLayout, nwItemClass
|
from nw.constants import nwItemLayout, nwItemClass, nwFiles
|
||||||
|
|
||||||
keyDelay = 2
|
keyDelay = 2
|
||||||
typeDelay = 1
|
typeDelay = 1
|
||||||
@@ -228,48 +228,20 @@ def testWritingStatsExport(qtbot, monkeypatch, yesToAll, nwFuncTemp, nwTemp):
|
|||||||
# Create new, save, close project
|
# Create new, save, close project
|
||||||
nwGUI.theProject.projTree.setSeed(42)
|
nwGUI.theProject.projTree.setSeed(42)
|
||||||
assert nwGUI.newProject({"projPath": nwFuncTemp})
|
assert nwGUI.newProject({"projPath": nwFuncTemp})
|
||||||
|
qtbot.wait(200)
|
||||||
assert nwGUI.saveProject()
|
assert nwGUI.saveProject()
|
||||||
assert nwGUI.closeProject()
|
assert nwGUI.closeProject()
|
||||||
qtbot.wait(stepDelay)
|
qtbot.wait(stepDelay)
|
||||||
|
|
||||||
# Check that we cannot open when there is no project
|
sessFile = os.path.join(nwFuncTemp, "meta", nwFiles.SESS_STATS)
|
||||||
nwGUI.mainMenu.aWritingStats.activate(QAction.Trigger)
|
with open(sessFile, mode="w+", encoding="utf-8") as outFile:
|
||||||
assert getGuiItem("GuiWritingStats") is None
|
outFile.write(
|
||||||
|
"# Start Time End Time Novel Notes\n"
|
||||||
assert nwGUI.openProject(nwFuncTemp)
|
"2020-01-01 21:00:00 2020-01-01 21:00:05 6 0\n"
|
||||||
qtbot.wait(stepDelay)
|
"2020-01-03 21:00:00 2020-01-03 21:00:15 125 0\n"
|
||||||
|
"2020-01-03 21:30:00 2020-01-03 21:30:15 125 5\n"
|
||||||
# Add some text to the scene file
|
"2020-01-06 21:00:00 2020-01-06 21:00:10 125 5\n"
|
||||||
assert nwGUI.openDocument("0e17daca5f3e1")
|
)
|
||||||
assert nwGUI.docEditor.insertText(
|
|
||||||
"# Scene One\n\n"
|
|
||||||
"It was the best of times, it was the worst of times, it was the age of wisdom, it was "
|
|
||||||
"the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it "
|
|
||||||
"was the season of Light, it was the season of Darkness, it was the spring of hope, it "
|
|
||||||
"was the winter of despair, we had everything before us, we had nothing before us, we "
|
|
||||||
"were all going direct to Heaven, we were all going direct the other way – in short, the "
|
|
||||||
"period was so far like the present period, that some of its noisiest authorities "
|
|
||||||
"insisted on its being received, for good or for evil, in the superlative degree of "
|
|
||||||
"comparison only.\n\n"
|
|
||||||
)
|
|
||||||
assert nwGUI.saveDocument()
|
|
||||||
|
|
||||||
# Add a note file with some text
|
|
||||||
nwGUI.setFocus(1)
|
|
||||||
nwGUI.treeView.clearSelection()
|
|
||||||
nwGUI.treeView._getTreeItem("71ee45a3c0db9").setSelected(True)
|
|
||||||
nwGUI.treeView.newTreeItem(nwItemType.FILE, None)
|
|
||||||
assert nwGUI.openSelectedItem()
|
|
||||||
assert nwGUI.docEditor.insertText(
|
|
||||||
"# Jane Doe\n\n"
|
|
||||||
"All about Jane.\n\n"
|
|
||||||
)
|
|
||||||
assert nwGUI.saveDocument()
|
|
||||||
qtbot.wait(500) # Ensures that the session length is > 0
|
|
||||||
|
|
||||||
assert nwGUI.saveProject()
|
|
||||||
assert nwGUI.closeProject()
|
|
||||||
qtbot.wait(stepDelay)
|
|
||||||
|
|
||||||
# Open again, and check the stats
|
# Open again, and check the stats
|
||||||
assert nwGUI.openProject(nwFuncTemp)
|
assert nwGUI.openProject(nwFuncTemp)
|
||||||
@@ -288,19 +260,21 @@ def testWritingStatsExport(qtbot, monkeypatch, yesToAll, nwFuncTemp, nwTemp):
|
|||||||
|
|
||||||
monkeypatch.setattr(QFileDialog, "getSaveFileName", lambda ss, tt, pp, options: (pp, ""))
|
monkeypatch.setattr(QFileDialog, "getSaveFileName", lambda ss, tt, pp, options: (pp, ""))
|
||||||
assert sessLog._saveData(sessLog.FMT_CSV)
|
assert sessLog._saveData(sessLog.FMT_CSV)
|
||||||
qtbot.wait(stepDelay)
|
qtbot.wait(100)
|
||||||
assert sessLog._saveData(sessLog.FMT_JSON)
|
assert sessLog._saveData(sessLog.FMT_JSON)
|
||||||
qtbot.wait(stepDelay)
|
qtbot.wait(100)
|
||||||
|
|
||||||
jsonStats = os.path.join(nwFuncTemp, "sessionStats.json")
|
jsonStats = os.path.join(nwFuncTemp, "sessionStats.json")
|
||||||
with open(jsonStats, mode="r", encoding="utf-8") as inFile:
|
with open(jsonStats, mode="r", encoding="utf-8") as inFile:
|
||||||
jsonData = json.loads(inFile.read())
|
jsonData = json.loads(inFile.read())
|
||||||
|
|
||||||
assert len(jsonData) == 2
|
qtbot.wait(stepDelay)
|
||||||
assert jsonData[1]["length"] >= 0
|
|
||||||
assert jsonData[1]["newWords"] == 126
|
assert len(jsonData) == 3
|
||||||
assert jsonData[1]["novelWords"] == 127
|
assert jsonData[1]["length"] >= 14.0
|
||||||
assert jsonData[1]["noteWords"] == 5
|
assert jsonData[1]["newWords"] == 119
|
||||||
|
assert jsonData[1]["novelWords"] == 125
|
||||||
|
assert jsonData[1]["noteWords"] == 0
|
||||||
|
|
||||||
# No Novel Files
|
# No Novel Files
|
||||||
qtbot.mouseClick(sessLog.incNovel, Qt.LeftButton)
|
qtbot.mouseClick(sessLog.incNovel, Qt.LeftButton)
|
||||||
@@ -313,9 +287,9 @@ def testWritingStatsExport(qtbot, monkeypatch, yesToAll, nwFuncTemp, nwTemp):
|
|||||||
jsonData = json.loads(inFile.read())
|
jsonData = json.loads(inFile.read())
|
||||||
|
|
||||||
assert len(jsonData) == 1
|
assert len(jsonData) == 1
|
||||||
assert jsonData[0]["length"] >= 0
|
assert jsonData[0]["length"] >= 14.0
|
||||||
assert jsonData[0]["newWords"] == 5
|
assert jsonData[0]["newWords"] == 5
|
||||||
assert jsonData[0]["novelWords"] == 127
|
assert jsonData[0]["novelWords"] == 125
|
||||||
assert jsonData[0]["noteWords"] == 5
|
assert jsonData[0]["noteWords"] == 5
|
||||||
|
|
||||||
# No Note Files
|
# No Note Files
|
||||||
@@ -330,10 +304,10 @@ def testWritingStatsExport(qtbot, monkeypatch, yesToAll, nwFuncTemp, nwTemp):
|
|||||||
jsonData = json.loads(inFile.read())
|
jsonData = json.loads(inFile.read())
|
||||||
|
|
||||||
assert len(jsonData) == 2
|
assert len(jsonData) == 2
|
||||||
assert jsonData[1]["length"] >= 0
|
assert jsonData[1]["length"] >= 14.0
|
||||||
assert jsonData[1]["newWords"] == 121
|
assert jsonData[1]["newWords"] == 119
|
||||||
assert jsonData[1]["novelWords"] == 127
|
assert jsonData[1]["novelWords"] == 125
|
||||||
assert jsonData[1]["noteWords"] == 5
|
assert jsonData[1]["noteWords"] == 0
|
||||||
|
|
||||||
# No Negative Entries
|
# No Negative Entries
|
||||||
qtbot.mouseClick(sessLog.incNotes, Qt.LeftButton)
|
qtbot.mouseClick(sessLog.incNotes, Qt.LeftButton)
|
||||||
@@ -346,7 +320,7 @@ def testWritingStatsExport(qtbot, monkeypatch, yesToAll, nwFuncTemp, nwTemp):
|
|||||||
with open(jsonStats, mode="r", encoding="utf-8") as inFile:
|
with open(jsonStats, mode="r", encoding="utf-8") as inFile:
|
||||||
jsonData = json.loads(inFile.read())
|
jsonData = json.loads(inFile.read())
|
||||||
|
|
||||||
assert len(jsonData) == 2
|
assert len(jsonData) == 3
|
||||||
|
|
||||||
# Un-hide Zero Entries
|
# Un-hide Zero Entries
|
||||||
qtbot.mouseClick(sessLog.hideNegative, Qt.LeftButton)
|
qtbot.mouseClick(sessLog.hideNegative, Qt.LeftButton)
|
||||||
@@ -359,7 +333,7 @@ def testWritingStatsExport(qtbot, monkeypatch, yesToAll, nwFuncTemp, nwTemp):
|
|||||||
with open(jsonStats, mode="r", encoding="utf-8") as inFile:
|
with open(jsonStats, mode="r", encoding="utf-8") as inFile:
|
||||||
jsonData = json.loads(inFile.read())
|
jsonData = json.loads(inFile.read())
|
||||||
|
|
||||||
assert len(jsonData) == 2
|
assert len(jsonData) == 4
|
||||||
|
|
||||||
# Group by Day
|
# Group by Day
|
||||||
qtbot.mouseClick(sessLog.groupByDay, Qt.LeftButton)
|
qtbot.mouseClick(sessLog.groupByDay, Qt.LeftButton)
|
||||||
@@ -373,11 +347,13 @@ def testWritingStatsExport(qtbot, monkeypatch, yesToAll, nwFuncTemp, nwTemp):
|
|||||||
|
|
||||||
# Check against both 1 and 2 as this can be 2 if test was started just before midnight.
|
# Check against both 1 and 2 as this can be 2 if test was started just before midnight.
|
||||||
# A failed test should in any case produce a 4
|
# A failed test should in any case produce a 4
|
||||||
assert len(jsonData) in (1, 2)
|
assert len(jsonData) == 3
|
||||||
|
|
||||||
# qtbot.stopForInteraction()
|
# qtbot.stopForInteraction()
|
||||||
|
|
||||||
sessLog._doClose()
|
sessLog._doClose()
|
||||||
|
assert nwGUI.closeProject()
|
||||||
|
qtbot.wait(stepDelay)
|
||||||
nwGUI.closeMain()
|
nwGUI.closeMain()
|
||||||
|
|
||||||
@pytest.mark.gui
|
@pytest.mark.gui
|
||||||
@@ -1057,6 +1033,7 @@ def testPreferences(qtbot, monkeypatch, yesToAll, nwMinimal, nwTemp, nwRef, tmpC
|
|||||||
nwGUI.mainConf = tmpConf
|
nwGUI.mainConf = tmpConf
|
||||||
nwPrefs.mainConf = tmpConf
|
nwPrefs.mainConf = tmpConf
|
||||||
nwPrefs.tabGeneral.mainConf = tmpConf
|
nwPrefs.tabGeneral.mainConf = tmpConf
|
||||||
|
nwPrefs.tabProjects.mainConf = tmpConf
|
||||||
nwPrefs.tabLayout.mainConf = tmpConf
|
nwPrefs.tabLayout.mainConf = tmpConf
|
||||||
nwPrefs.tabEditing.mainConf = tmpConf
|
nwPrefs.tabEditing.mainConf = tmpConf
|
||||||
nwPrefs.tabAutoRep.mainConf = tmpConf
|
nwPrefs.tabAutoRep.mainConf = tmpConf
|
||||||
@@ -1065,7 +1042,6 @@ def testPreferences(qtbot, monkeypatch, yesToAll, nwMinimal, nwTemp, nwRef, tmpC
|
|||||||
qtbot.wait(keyDelay)
|
qtbot.wait(keyDelay)
|
||||||
tabGeneral = nwPrefs.tabGeneral
|
tabGeneral = nwPrefs.tabGeneral
|
||||||
nwPrefs._tabBox.setCurrentWidget(tabGeneral)
|
nwPrefs._tabBox.setCurrentWidget(tabGeneral)
|
||||||
tabGeneral.backupPath = "no/where"
|
|
||||||
|
|
||||||
qtbot.wait(keyDelay)
|
qtbot.wait(keyDelay)
|
||||||
assert not tabGeneral.preferDarkIcons.isChecked()
|
assert not tabGeneral.preferDarkIcons.isChecked()
|
||||||
@@ -1077,27 +1053,45 @@ def testPreferences(qtbot, monkeypatch, yesToAll, nwMinimal, nwTemp, nwRef, tmpC
|
|||||||
qtbot.mouseClick(tabGeneral.showFullPath, Qt.LeftButton)
|
qtbot.mouseClick(tabGeneral.showFullPath, Qt.LeftButton)
|
||||||
assert not tabGeneral.showFullPath.isChecked()
|
assert not tabGeneral.showFullPath.isChecked()
|
||||||
|
|
||||||
# Check Browse button
|
qtbot.wait(keyDelay)
|
||||||
monkeypatch.setattr(QFileDialog, "getExistingDirectory", lambda *args, **kwargs: "")
|
assert not tabGeneral.hideVScroll.isChecked()
|
||||||
assert not tabGeneral._backupFolder()
|
qtbot.mouseClick(tabGeneral.hideVScroll, Qt.LeftButton)
|
||||||
monkeypatch.setattr(QFileDialog, "getExistingDirectory", lambda *args, **kwargs: "some/dir")
|
assert tabGeneral.hideVScroll.isChecked()
|
||||||
qtbot.mouseClick(tabGeneral.backupGetPath, Qt.LeftButton)
|
|
||||||
|
qtbot.wait(keyDelay)
|
||||||
|
assert not tabGeneral.hideHScroll.isChecked()
|
||||||
|
qtbot.mouseClick(tabGeneral.hideHScroll, Qt.LeftButton)
|
||||||
|
assert tabGeneral.hideHScroll.isChecked()
|
||||||
|
|
||||||
# Check font button
|
# Check font button
|
||||||
monkeypatch.setattr(QFontDialog, "getFont", lambda font, obj: (font, True))
|
monkeypatch.setattr(QFontDialog, "getFont", lambda font, obj: (font, True))
|
||||||
qtbot.mouseClick(tabGeneral.fontButton, Qt.LeftButton)
|
qtbot.mouseClick(tabGeneral.fontButton, Qt.LeftButton)
|
||||||
|
|
||||||
qtbot.wait(keyDelay)
|
qtbot.wait(keyDelay)
|
||||||
assert not tabGeneral.backupOnClose.isChecked()
|
tabGeneral.guiFontSize.setValue(12)
|
||||||
qtbot.mouseClick(tabGeneral.backupOnClose, Qt.LeftButton)
|
|
||||||
assert tabGeneral.backupOnClose.isChecked()
|
# Projects Settings
|
||||||
|
qtbot.wait(keyDelay)
|
||||||
|
tabProjects = nwPrefs.tabProjects
|
||||||
|
nwPrefs._tabBox.setCurrentWidget(tabProjects)
|
||||||
|
tabProjects.backupPath = "no/where"
|
||||||
|
|
||||||
qtbot.wait(keyDelay)
|
qtbot.wait(keyDelay)
|
||||||
tabGeneral.guiFontSize.setValue(12)
|
assert not tabProjects.backupOnClose.isChecked()
|
||||||
tabGeneral.autoSaveDoc.setValue(20)
|
qtbot.mouseClick(tabProjects.backupOnClose, Qt.LeftButton)
|
||||||
tabGeneral.autoSaveProj.setValue(40)
|
assert tabProjects.backupOnClose.isChecked()
|
||||||
|
|
||||||
# Text Layour Settings
|
# Check Browse button
|
||||||
|
monkeypatch.setattr(QFileDialog, "getExistingDirectory", lambda *args, **kwargs: "")
|
||||||
|
assert not tabProjects._backupFolder()
|
||||||
|
monkeypatch.setattr(QFileDialog, "getExistingDirectory", lambda *args, **kwargs: "some/dir")
|
||||||
|
qtbot.mouseClick(tabProjects.backupGetPath, Qt.LeftButton)
|
||||||
|
|
||||||
|
qtbot.wait(keyDelay)
|
||||||
|
tabProjects.autoSaveDoc.setValue(20)
|
||||||
|
tabProjects.autoSaveProj.setValue(40)
|
||||||
|
|
||||||
|
# Text Layout Settings
|
||||||
qtbot.wait(keyDelay)
|
qtbot.wait(keyDelay)
|
||||||
tabLayout = nwPrefs.tabLayout
|
tabLayout = nwPrefs.tabLayout
|
||||||
nwPrefs._tabBox.setCurrentWidget(tabLayout)
|
nwPrefs._tabBox.setCurrentWidget(tabLayout)
|
||||||
@@ -1127,6 +1121,16 @@ def testPreferences(qtbot, monkeypatch, yesToAll, nwMinimal, nwTemp, nwRef, tmpC
|
|||||||
qtbot.mouseClick(tabLayout.textJustify, Qt.LeftButton)
|
qtbot.mouseClick(tabLayout.textJustify, Qt.LeftButton)
|
||||||
assert not tabLayout.textJustify.isChecked()
|
assert not tabLayout.textJustify.isChecked()
|
||||||
|
|
||||||
|
qtbot.wait(keyDelay)
|
||||||
|
assert tabLayout.scrollPastEnd.isChecked()
|
||||||
|
qtbot.mouseClick(tabLayout.scrollPastEnd, Qt.LeftButton)
|
||||||
|
assert not tabLayout.scrollPastEnd.isChecked()
|
||||||
|
|
||||||
|
qtbot.wait(keyDelay)
|
||||||
|
assert not tabLayout.scollWithCursor.isChecked()
|
||||||
|
qtbot.mouseClick(tabLayout.scollWithCursor, Qt.LeftButton)
|
||||||
|
assert tabLayout.scollWithCursor.isChecked()
|
||||||
|
|
||||||
# Editor Settings
|
# Editor Settings
|
||||||
qtbot.wait(keyDelay)
|
qtbot.wait(keyDelay)
|
||||||
tabEditing = nwPrefs.tabEditing
|
tabEditing = nwPrefs.tabEditing
|
||||||
@@ -1198,7 +1202,7 @@ def testPreferences(qtbot, monkeypatch, yesToAll, nwMinimal, nwTemp, nwRef, tmpC
|
|||||||
ignoreLines = [
|
ignoreLines = [
|
||||||
2, # Timestamp
|
2, # Timestamp
|
||||||
11, 12, 13, 14, 15, 16, 17, # Window sizes
|
11, 12, 13, 14, 15, 16, 17, # Window sizes
|
||||||
7, 25, # Fonts (depends on system default)
|
7, 27, # Fonts (depends on system default)
|
||||||
]
|
]
|
||||||
assert cmpFiles(testConf, refConf, ignoreLines)
|
assert cmpFiles(testConf, refConf, ignoreLines)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user