Refactor how editor document is saved, and always save cursor position
This commit is contained in:
@@ -477,7 +477,6 @@ class GuiDocEditor(QPlainTextEdit):
|
|||||||
cC, wC, pC = standardCounter(docText)
|
cC, wC, pC = standardCounter(docText)
|
||||||
self._updateDocCounts(cC, wC, pC)
|
self._updateDocCounts(cC, wC, pC)
|
||||||
|
|
||||||
self.saveCursorPosition()
|
|
||||||
if not self._nwDocument.writeDocument(docText):
|
if not self._nwDocument.writeDocument(docText):
|
||||||
saveOk = False
|
saveOk = False
|
||||||
if self._nwDocument.hashError:
|
if self._nwDocument.hashError:
|
||||||
|
|||||||
@@ -32,10 +32,8 @@ from enum import Enum
|
|||||||
from time import time
|
from time import time
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from PyQt5.QtCore import QPoint, QTimer, Qt, pyqtSignal, pyqtSlot
|
from PyQt5.QtCore import QPoint, Qt, QTimer, pyqtSignal, pyqtSlot
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import QDragEnterEvent, QDragMoveEvent, QDropEvent, QIcon, QMouseEvent, QPalette
|
||||||
QDragEnterEvent, QDragMoveEvent, QDropEvent, QIcon, QMouseEvent, QPalette
|
|
||||||
)
|
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
QAbstractItemView, QAction, QDialog, QFrame, QHBoxLayout, QHeaderView,
|
QAbstractItemView, QAction, QDialog, QFrame, QHBoxLayout, QHeaderView,
|
||||||
QLabel, QMenu, QShortcut, QTreeWidget, QTreeWidgetItem, QVBoxLayout,
|
QLabel, QMenu, QShortcut, QTreeWidget, QTreeWidgetItem, QVBoxLayout,
|
||||||
@@ -44,19 +42,19 @@ from PyQt5.QtWidgets import (
|
|||||||
|
|
||||||
from novelwriter import CONFIG, SHARED
|
from novelwriter import CONFIG, SHARED
|
||||||
from novelwriter.common import minmax
|
from novelwriter.common import minmax
|
||||||
from novelwriter.constants import nwHeaders, nwUnicode, trConst, nwLabels
|
from novelwriter.constants import nwHeaders, nwLabels, nwUnicode, trConst
|
||||||
from novelwriter.core.coretools import DocDuplicator, DocMerger, DocSplitter
|
from novelwriter.core.coretools import DocDuplicator, DocMerger, DocSplitter
|
||||||
from novelwriter.core.item import NWItem
|
from novelwriter.core.item import NWItem
|
||||||
from novelwriter.dialogs.docmerge import GuiDocMerge
|
from novelwriter.dialogs.docmerge import GuiDocMerge
|
||||||
from novelwriter.dialogs.docsplit import GuiDocSplit
|
from novelwriter.dialogs.docsplit import GuiDocSplit
|
||||||
from novelwriter.dialogs.editlabel import GuiEditLabel
|
from novelwriter.dialogs.editlabel import GuiEditLabel
|
||||||
from novelwriter.dialogs.projectsettings import GuiProjectSettings
|
from novelwriter.dialogs.projectsettings import GuiProjectSettings
|
||||||
from novelwriter.enum import nwDocMode, nwItemType, nwItemClass, nwItemLayout
|
from novelwriter.enum import nwDocMode, nwItemClass, nwItemLayout, nwItemType
|
||||||
from novelwriter.extensions.modified import NIconToolButton
|
from novelwriter.extensions.modified import NIconToolButton
|
||||||
from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON
|
from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON
|
||||||
from novelwriter.types import (
|
from novelwriter.types import (
|
||||||
QtAlignLeft, QtAlignRight, QtMouseLeft, QtMouseMiddle, QtSizeExpanding,
|
QtAlignLeft, QtAlignRight, QtMouseLeft, QtMouseMiddle, QtSizeExpanding,
|
||||||
QtUserRole,
|
QtUserRole
|
||||||
)
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING: # pragma: no cover
|
if TYPE_CHECKING: # pragma: no cover
|
||||||
@@ -1424,7 +1422,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
# Save the open document first, in case it's part of merge
|
# Save the open document first, in case it's part of merge
|
||||||
self.mainGui.saveDocument()
|
SHARED.saveDocument()
|
||||||
|
|
||||||
# Create merge object, and append docs
|
# Create merge object, and append docs
|
||||||
docMerger = DocMerger(SHARED.project)
|
docMerger = DocMerger(SHARED.project)
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ class GuiProjectSearch(QWidget):
|
|||||||
if not self._blocked:
|
if not self._blocked:
|
||||||
QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
||||||
start = time()
|
start = time()
|
||||||
SHARED.mainGui.saveDocument()
|
SHARED.saveDocument()
|
||||||
self._blocked = True
|
self._blocked = True
|
||||||
self._map = {}
|
self._map = {}
|
||||||
self.searchResult.clear()
|
self.searchResult.clear()
|
||||||
|
|||||||
+7
-10
@@ -369,9 +369,7 @@ class GuiMain(QMainWindow):
|
|||||||
if not msgYes:
|
if not msgYes:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if self.docEditor.docChanged:
|
self.saveDocument()
|
||||||
self.saveDocument()
|
|
||||||
|
|
||||||
saveOK = self.saveProject()
|
saveOK = self.saveProject()
|
||||||
doBackup = False
|
doBackup = False
|
||||||
if SHARED.project.data.doBackup and CONFIG.backupOnClose:
|
if SHARED.project.data.doBackup and CONFIG.backupOnClose:
|
||||||
@@ -514,9 +512,7 @@ class GuiMain(QMainWindow):
|
|||||||
# Disable focus mode if it is active
|
# Disable focus mode if it is active
|
||||||
if SHARED.focusMode:
|
if SHARED.focusMode:
|
||||||
SHARED.setFocusMode(False)
|
SHARED.setFocusMode(False)
|
||||||
self.docEditor.saveCursorPosition()
|
self.saveDocument()
|
||||||
if self.docEditor.docChanged:
|
|
||||||
self.saveDocument()
|
|
||||||
self.docEditor.clearEditor()
|
self.docEditor.clearEditor()
|
||||||
if not beforeOpen:
|
if not beforeOpen:
|
||||||
self.novelView.setActiveHandle(None)
|
self.novelView.setActiveHandle(None)
|
||||||
@@ -587,7 +583,8 @@ class GuiMain(QMainWindow):
|
|||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def saveDocument(self) -> None:
|
def saveDocument(self) -> None:
|
||||||
"""Save the current documents."""
|
"""Save the current documents."""
|
||||||
if SHARED.hasProject:
|
self.docEditor.saveCursorPosition()
|
||||||
|
if SHARED.hasProject and self.docEditor.docChanged:
|
||||||
self.docEditor.saveText()
|
self.docEditor.saveText()
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1133,7 +1130,7 @@ class GuiMain(QMainWindow):
|
|||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def _reloadViewer(self) -> None:
|
def _reloadViewer(self) -> None:
|
||||||
"""Reload the document in the viewer."""
|
"""Reload the document in the viewer."""
|
||||||
if self.docEditor.docChanged and self.docEditor.docHandle == self.docViewer.docHandle:
|
if self.docEditor.docHandle == self.docViewer.docHandle:
|
||||||
# If the two panels have the same document, save any changes in the editor
|
# If the two panels have the same document, save any changes in the editor
|
||||||
self.saveDocument()
|
self.saveDocument()
|
||||||
self.docViewer.reloadText()
|
self.docViewer.reloadText()
|
||||||
@@ -1213,7 +1210,7 @@ class GuiMain(QMainWindow):
|
|||||||
doSave &= SHARED.project.projChanged
|
doSave &= SHARED.project.projChanged
|
||||||
doSave &= SHARED.project.storage.isOpen()
|
doSave &= SHARED.project.storage.isOpen()
|
||||||
if doSave:
|
if doSave:
|
||||||
logger.debug("Autosaving project")
|
logger.debug("Auto-saving project")
|
||||||
self.saveProject(autoSave=True)
|
self.saveProject(autoSave=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1221,7 +1218,7 @@ class GuiMain(QMainWindow):
|
|||||||
def _autoSaveDocument(self) -> None:
|
def _autoSaveDocument(self) -> None:
|
||||||
"""Autosave of the document. This is a timer-activated slot."""
|
"""Autosave of the document. This is a timer-activated slot."""
|
||||||
if SHARED.hasProject and self.docEditor.docChanged:
|
if SHARED.hasProject and self.docEditor.docChanged:
|
||||||
logger.debug("Autosaving document")
|
logger.debug("Auto-saving document")
|
||||||
self.saveDocument()
|
self.saveDocument()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -171,6 +171,11 @@ class SharedData(QObject):
|
|||||||
logger.debug("Thread Pool Max Count: %d", QThreadPool.globalInstance().maxThreadCount())
|
logger.debug("Thread Pool Max Count: %d", QThreadPool.globalInstance().maxThreadCount())
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def saveDocument(self) -> None:
|
||||||
|
"""Forward save document call to main GUI."""
|
||||||
|
self.mainGui.saveDocument()
|
||||||
|
return
|
||||||
|
|
||||||
def openProject(self, path: str | Path, clearLock: bool = False) -> bool:
|
def openProject(self, path: str | Path, clearLock: bool = False) -> bool:
|
||||||
"""Open a project."""
|
"""Open a project."""
|
||||||
if self.project.isValid:
|
if self.project.isValid:
|
||||||
|
|||||||
@@ -327,7 +327,7 @@ class GuiManuscriptBuild(QDialog):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
# Make sure editor content is saved before we start
|
# Make sure editor content is saved before we start
|
||||||
SHARED.mainGui.saveDocument()
|
SHARED.saveDocument()
|
||||||
|
|
||||||
docBuild = NWBuildDocument(SHARED.project, self._build)
|
docBuild = NWBuildDocument(SHARED.project, self._build)
|
||||||
docBuild.queueAll()
|
docBuild.queueAll()
|
||||||
|
|||||||
@@ -339,7 +339,7 @@ class GuiManuscript(NToolDialog):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Make sure editor content is saved before we start
|
# Make sure editor content is saved before we start
|
||||||
SHARED.mainGui.saveDocument()
|
SHARED.saveDocument()
|
||||||
|
|
||||||
docBuild = NWBuildDocument(SHARED.project, build)
|
docBuild = NWBuildDocument(SHARED.project, build)
|
||||||
docBuild.setPreviewMode(True)
|
docBuild.setPreviewMode(True)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version='1.0' encoding='utf-8'?>
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
<novelWriterXML appVersion="2.5a3" hexVersion="0x020500a3" fileVersion="1.5" fileRevision="4" timeStamp="2024-05-01 19:43:08">
|
<novelWriterXML appVersion="2.5a3" hexVersion="0x020500a3" fileVersion="1.5" fileRevision="4" timeStamp="2024-05-02 21:45:22">
|
||||||
<project id="e2be99af-f9bf-4403-857a-c3d1ac25abea" saveCount="1917" autoCount="274" editTime="87503">
|
<project id="e2be99af-f9bf-4403-857a-c3d1ac25abea" saveCount="1918" autoCount="274" editTime="87508">
|
||||||
<name>Sample Project</name>
|
<name>Sample Project</name>
|
||||||
<author>Jane Smith</author>
|
<author>Jane Smith</author>
|
||||||
</project>
|
</project>
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
<name status="sf24ce6" import="ia857f0" active="yes">Chapter One</name>
|
<name status="sf24ce6" import="ia857f0" active="yes">Chapter One</name>
|
||||||
</item>
|
</item>
|
||||||
<item handle="636b6aa9b697b" parent="6a2d6d5f4f401" root="7031beac91f75" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
<item handle="636b6aa9b697b" parent="6a2d6d5f4f401" root="7031beac91f75" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||||
<meta expanded="no" heading="H3" charCount="2953" wordCount="520" paraCount="15" cursorPos="2155" />
|
<meta expanded="no" heading="H3" charCount="2953" wordCount="520" paraCount="15" cursorPos="19" />
|
||||||
<name status="s90e6c9" import="ia857f0" active="yes">Making a Scene</name>
|
<name status="s90e6c9" import="ia857f0" active="yes">Making a Scene</name>
|
||||||
</item>
|
</item>
|
||||||
<item handle="bc0cbd2a407f3" parent="6a2d6d5f4f401" root="7031beac91f75" order="1" type="FILE" class="NOVEL" layout="DOCUMENT">
|
<item handle="bc0cbd2a407f3" parent="6a2d6d5f4f401" root="7031beac91f75" order="1" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||||
|
|||||||
Reference in New Issue
Block a user