Autosaving works, and document and project tracks whether they have been changed or not.

This commit is contained in:
Veronica K. B. Olsen
2019-05-05 00:11:46 +02:00
parent 9ea70aeeaf
commit 9565b14d8b
8 changed files with 97 additions and 20 deletions
+21 -3
View File
@@ -57,6 +57,10 @@ class Config:
self.treeColWidth = [120, 30, 50]
self.mainPanePos = [300, 800]
## Project
self.autoSaveProj = 60
self.autoSaveDoc = 30
## Text Editor
self.textFixedW = True
self.textWidth = 600
@@ -115,6 +119,14 @@ class Config:
confParser.get(cnfSec,"mainpane"), 2, self.mainPanePos
)
## 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")
## Editor
cnfSec = "Editor"
if confParser.has_section(cnfSec):
@@ -169,9 +181,15 @@ class Config:
## 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,"geometry", self.packList(self.winGeometry))
confParser.set(cnfSec,"treecols", self.packList(self.treeColWidth))
confParser.set(cnfSec,"mainpane", self.packList(self.mainPanePos))
## Project
cnfSec = "Project"
confParser.add_section(cnfSec)
confParser.set(cnfSec,"autosaveproject", str(self.autoSaveProj))
confParser.set(cnfSec,"autosavedoc", str(self.autoSaveDoc))
## Editor
cnfSec = "Editor"
+2 -2
View File
@@ -204,7 +204,7 @@ class GuiDocEditor(QTextEdit):
self.wcTimer.start()
if self.mainConf.doReplace and not self.hasSelection:
self._docAutoReplace(self.theDoc.findBlock(thePos))
logger.verbose("Doc change signal took %.3f µs" % ((time()-self.lastEdit)*1e6))
# logger.verbose("Doc change signal took %.3f µs" % ((time()-self.lastEdit)*1e6))
return
def _docAutoReplace(self, theBlock):
@@ -267,7 +267,7 @@ class GuiDocEditor(QTextEdit):
"""
sinceActive = time()-self.lastEdit
if sinceActive > 5*self.wcInterval:
logger.verbose("Stopping word count timer due to no activity over the last %.3f seconds" % sinceActive)
logger.debug("Stopping word count timer due to no activity over the last %.3f seconds" % sinceActive)
self.wcTimer.stop()
elif self.wCounter.isRunning():
logger.verbose("Word counter thread is busy")
+2 -2
View File
@@ -143,9 +143,9 @@ class GuiDocHighlighter(QSyntaxHighlighter):
}
))
# Build a QRegExp for each pattern
# Build a QRegExp for each pattern and for the spell checker
self.rules = [(QRegularExpression(a),b) for (a,b) in self.hRules]
self.spellRx = QRegularExpression(r"[\w\'{:s}]+".format(self.mainConf.fmtSingleQuotes[1]))
self.spellRx = QRegularExpression(r"[\w\'{:s}]+".format(self.mainConf.fmtApostrophe))
logger.debug("DocHighlighter initialisation complete")
+7 -1
View File
@@ -137,7 +137,7 @@ class GuiDocTree(QTreeWidget):
trItem.setSelected(True)
self.theParent.editItem()
return
return True
def moveTreeItem(self, nStep):
"""Move an item up or down in the tree, but only if the treeView has focus. This also
@@ -163,6 +163,7 @@ class GuiDocTree(QTreeWidget):
pItem.insertChild(nIndex, cItem)
self.clearSelection()
cItem.setSelected(True)
self.theProject.projChanged = True
return
def saveTreeOrder(self):
@@ -208,6 +209,7 @@ class GuiDocTree(QTreeWidget):
nwItemS.setParent(self.theProject.trashRoot)
self.clearSelection()
trItemP.setSelected(True)
self.theProject.projChanged = True
elif nwItemS.itemType == nwItemType.FOLDER:
logger.debug("User requested folder %s deleted" % tHandle)
@@ -220,6 +222,7 @@ class GuiDocTree(QTreeWidget):
trItemP.takeChild(tIndex)
self.clearSelection()
trItemP.setSelected(True)
self.theProject.projChanged = True
else:
self.theParent.makeAlert(["Cannot delete folder.","It is not empty."],2)
return
@@ -230,6 +233,7 @@ class GuiDocTree(QTreeWidget):
if trItemS.childCount() == 0:
self.takeTopLevelItem(tIndex)
self.theParent.mainMenu.setAvailableRoot()
self.theProject.projChanged = True
else:
self.theParent.makeAlert(["Cannot delete root folder.","It is not empty."],2)
return
@@ -387,6 +391,7 @@ class GuiDocTree(QTreeWidget):
pHandle = trItemP.text(self.C_HANDLE)
nwItemS.setParent(pHandle)
self.setTreeItemValues(tHandle)
self.theProject.projChanged = True
return
def _moveOrphanedItem(self, tHandle, dHandle):
@@ -401,6 +406,7 @@ class GuiDocTree(QTreeWidget):
pHandle = trItemP.text(self.C_HANDLE)
nwItemS.setParent(pHandle)
self.setTreeItemValues(tHandle)
self.theProject.projChanged = True
return
##
+46 -1
View File
@@ -16,7 +16,7 @@ import nw
from os import path
from PyQt5.QtWidgets import QWidget, QMainWindow, QVBoxLayout, QFrame, QSplitter, QFileDialog, QStackedWidget, QShortcut, QMessageBox
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt
from PyQt5.QtCore import Qt, QTimer
from nw.gui.doctree import GuiDocTree
from nw.gui.doceditor import GuiDocEditor
@@ -91,6 +91,16 @@ class GuiMain(QMainWindow):
theCss = inFile.read()
self.setStyleSheet(theCss)
self.asProjTimer = QTimer()
self.asProjTimer.setInterval(int(self.mainConf.autoSaveProj*1000))
self.asProjTimer.timeout.connect(self._autoSaveProject)
self.asProjTimer.start()
self.asDocTimer = QTimer()
self.asDocTimer.setInterval(int(self.mainConf.autoSaveDoc*1000))
self.asDocTimer.timeout.connect(self._autoSaveDocument)
self.asDocTimer.start()
self.show()
logger.debug("GUI initialisation complete")
@@ -162,6 +172,8 @@ class GuiMain(QMainWindow):
##
def openDocument(self, tHandle):
if self._takeDocumentAction():
self.saveDocument()
self.stackPane.setCurrentIndex(self.stackDoc)
self.docEditor.setText(self.theDocument.openDocument(tHandle))
self.docEditor.changeWidth()
@@ -174,6 +186,7 @@ class GuiMain(QMainWindow):
self.theDocument.theItem.setWordCount(self.docEditor.wordCount)
self.theDocument.theItem.setParaCount(self.docEditor.paraCount)
self.theDocument.saveDocument(docHtml)
self.docEditor.theDoc.setModified(False)
return
##
@@ -245,6 +258,10 @@ class GuiMain(QMainWindow):
def closeMain(self):
logger.info("Exiting %s" % nw.__package__)
if self._takeDocumentAction():
self.saveDocument()
if self._takeProjectAction():
self.saveProject()
self.mainConf.setWinSize(self.width(), self.height())
self.mainConf.setTreeColWidths(self.treeView.getColumnSizes())
self.mainConf.setMainPanePos(self.splitMain.sizes())
@@ -270,6 +287,34 @@ class GuiMain(QMainWindow):
self.setWindowTitle(winTitle)
return True
def _autoSaveProject(self):
if self._takeProjectAction():
logger.debug("Autosaving project")
self.saveProject()
return
def _autoSaveDocument(self):
if self._takeDocumentAction():
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.stackPane.currentIndex() != self.stackDoc:
return False
if self.theDocument.theItem is None:
return False
if not self.docEditor.theDoc.isModified():
return False
return True
##
# Events
##
+15 -7
View File
@@ -33,6 +33,7 @@ class NWProject():
# Internal
self.mainConf = nw.CONFIG
self.theParent = theParent
self.projChanged = False
# Project Settings
self.projTree = None
@@ -111,6 +112,8 @@ class NWProject():
def clearProject(self):
self.projChanged = False
# Project Settings
self.projTree = {}
self.treeOrder = []
@@ -197,6 +200,7 @@ class NWProject():
self.theParent.statusBar.setStatus("Opened Project: %s" % self.projName)
self._scanProjectFolder()
self.projChanged = False
return True
@@ -255,6 +259,7 @@ class NWProject():
self.mainConf.setRecent(self.projPath)
self.theParent.statusBar.setStatus("Saved Project: %s" % self.projName)
self.projChanged = False
return True
@@ -264,14 +269,17 @@ class NWProject():
def setProjectPath(self, projPath):
self.projPath = projPath
self.projChanged = True
return True
def setProjectName(self, projName):
self.projName = projName.strip()
self.projChanged = True
return True
def setBookTitle(self, bookTitle):
self.bookTitle = bookTitle.strip()
self.projChanged = True
return True
def setBookAuthors(self, bookAuthors):
@@ -281,18 +289,16 @@ class NWProject():
if bookAuthor == "":
continue
self.bookAuthors.append(bookAuthor)
self.projChanged = True
return True
def setTreeOrder(self, newOrder):
if len(self.treeOrder) != len(newOrder):
logger.warning("Size of new and old tree order does not match")
self.treeOrder = newOrder
self.projChanged = True
return True
def setItemName(self, tHandle, theName):
self.projTree[tHandle].setName(theName)
return
##
# Get Functions
##
@@ -349,16 +355,16 @@ class NWProject():
continue
fHandle = fileItem[5]+fileItem[7:19]
if fHandle in self.treeOrder:
logger.verbose("Checking file %s, handle %s: OK" % (fileItem,fHandle))
logger.debug("Checking file %s, handle %s: OK" % (fileItem,fHandle))
else:
logger.verbose("Checking file %s, handle %s: Orphaned" % (fileItem,fHandle))
logger.debug("Checking file %s, handle %s: Orphaned" % (fileItem,fHandle))
orphanFiles.append(fHandle)
# Report status
if len(orphanFiles) > 0:
self.theParent.makeAlert("Found %d orphaned file(s) in project folder!" % len(orphanFiles),1)
else:
logger.verbose("File check OK")
logger.debug("File check OK")
return
# Handle orphans
@@ -396,6 +402,8 @@ class NWProject():
else:
logger.error("Only one trash folder allowed")
self.projChanged = True
return
def _makeStatusIcons(self):
@@ -13,6 +13,6 @@ Some text here would look good as well, and maybe some "dialogue"?
So, this is some text that weve been adding to this document. It is utterly meaningless text, but since this is just dummy text, that doesnt really matter. The text is perfectly happy to live in this document regardless.
This paragraph is also meaningless.
This paragraph is also meaningless. At least a bit.
+3 -3
View File
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="0.0.1" fileVersion="1.0" timeStamp="2019-05-04 22:24:32">
<novelWriterXML appVersion="0.0.1" fileVersion="1.0" timeStamp="2019-05-04 23:57:20">
<project>
<name>Sample Project</name>
<title>Sample Project</title>
@@ -50,8 +50,8 @@
<status>1</status>
<expanded>False</expanded>
<layout>SCENE</layout>
<charCount>376</charCount>
<wordCount>66</wordCount>
<charCount>392</charCount>
<wordCount>70</wordCount>
<paraCount>4</paraCount>
</item>
<item handle="bc0cbd2a407f3" order="2" parent="e7ded148d6e4a">