src/eric7/QScintilla/Editor.py

branch
eric7
changeset 10307
c685f4e12916
parent 10288
1f5c7f54c3cc
child 10331
c1a2ff7e3575
--- a/src/eric7/QScintilla/Editor.py	Mon Nov 13 11:53:55 2023 +0100
+++ b/src/eric7/QScintilla/Editor.py	Mon Nov 13 17:38:06 2023 +0100
@@ -317,6 +317,16 @@
         self.__markedText = ""
         self.__searchIndicatorLines = []
 
+        # set the autosave attributes
+        self.__autosaveInterval = Preferences.getEditor("AutosaveIntervalSeconds")
+        self.__autosaveManuallyDisabled = False
+
+        # initialize the autosave timer
+        self.__autosaveTimer = QTimer(self)
+        self.__autosaveTimer.setObjectName("AutosaveTimer")
+        self.__autosaveTimer.setSingleShot(True)
+        self.__autosaveTimer.timeout.connect(self.__autosave)
+
         # initialize some spellchecking stuff
         self.spell = None
         self.lastLine = 0
@@ -550,10 +560,6 @@
             if bnd.width() < req.width() or bnd.height() < req.height():
                 self.resize(bnd)
 
-        # set the autosave flag
-        self.autosaveEnabled = Preferences.getEditor("AutosaveInterval") > 0
-        self.autosaveManuallyDisabled = False
-
         # code coverage related attributes
         self.__coverageFile = ""
 
@@ -959,7 +965,7 @@
             self.tr("Autosave enabled"), self.__autosaveEnable
         )
         self.menuActs["AutosaveEnable"].setCheckable(True)
-        self.menuActs["AutosaveEnable"].setChecked(self.autosaveEnabled)
+        self.menuActs["AutosaveEnable"].setChecked(self.__autosaveInterval > 0)
         self.menuActs["TypingAidsEnabled"] = self.menu.addAction(
             self.tr("Typing aids enabled"), self.__toggleTypingAids
         )
@@ -2097,6 +2103,9 @@
         self.undoAvailable.emit(self.isUndoAvailable())
         self.redoAvailable.emit(self.isRedoAvailable())
 
+        if not m:
+            self.__autosaveTimer.stop()
+
     @pyqtSlot(int, int)
     def __cursorPositionChanged(self, line, index):
         """
@@ -2113,7 +2122,6 @@
         self.cursorChanged.emit(self.fileName, line + 1, index)
 
         if Preferences.getEditor("MarkOccurrencesEnabled"):
-            self.__markOccurrencesTimer.stop()
             self.__markOccurrencesTimer.start()
 
         if self.lastLine != line:
@@ -2407,23 +2415,31 @@
         @param annotationLinesAdded number of added/deleted annotation lines
             (integer)
         """
-        if (
-            mtype & (self.SC_MOD_INSERTTEXT | self.SC_MOD_DELETETEXT)
-            and linesAdded != 0
-            and self.breaks
-        ):
-            bps = []  # list of breakpoints
-            for handle, (ln, cond, temp, enabled, ignorecount) in self.breaks.items():
-                line = self.markerLine(handle) + 1
-                if ln != line:
-                    bps.append((ln, line))
-                    self.breaks[handle] = (line, cond, temp, enabled, ignorecount)
-            self.inLinesChanged = True
-            for ln, line in sorted(bps, reverse=linesAdded > 0):
-                index1 = self.breakpointModel.getBreakPointIndex(self.fileName, ln)
-                index2 = self.breakpointModel.index(index1.row(), 1)
-                self.breakpointModel.setData(index2, line)
-            self.inLinesChanged = False
+        if mtype & (self.SC_MOD_INSERTTEXT | self.SC_MOD_DELETETEXT):
+            # 1. set/reset the autosave timer
+            if self.__autosaveInterval > 0:
+                self.__autosaveTimer.start(self.__autosaveInterval * 1000)
+
+            # 2. move breakpoints if a line was inserted or deleted
+            if linesAdded != 0 and self.breaks:
+                bps = []  # list of breakpoints
+                for handle, (
+                    ln,
+                    cond,
+                    temp,
+                    enabled,
+                    ignorecount,
+                ) in self.breaks.items():
+                    line = self.markerLine(handle) + 1
+                    if ln != line:
+                        bps.append((ln, line))
+                        self.breaks[handle] = (line, cond, temp, enabled, ignorecount)
+                self.inLinesChanged = True
+                for ln, line in sorted(bps, reverse=linesAdded > 0):
+                    index1 = self.breakpointModel.getBreakPointIndex(self.fileName, ln)
+                    index2 = self.breakpointModel.index(index1.row(), 1)
+                    self.breakpointModel.setData(index2, line)
+                self.inLinesChanged = False
 
     def __restoreBreakpoints(self):
         """
@@ -3640,6 +3656,8 @@
 
         self.__loadEditorConfig(fn)
         self.editorAboutToBeSaved.emit(self.fileName)
+        if self.__autosaveTimer.isActive():
+            self.__autosaveTimer.stop()
         if self.writeFile(fn):
             if saveas:
                 self.__clearBreakpoints(self.fileName)
@@ -4734,7 +4752,12 @@
         self.__setCallTips()
 
         # set the autosave flags
-        self.autosaveEnabled = Preferences.getEditor("AutosaveInterval") > 0
+        self.__autosaveInterval = Preferences.getEditor("AutosaveIntervalSeconds")
+        if self.__autosaveInterval == 0:
+            self.__autosaveTimer.stop()
+        else:
+            if self.isModified():
+                self.__autosaveTimer.start(self.__autosaveInterval * 1000)
 
         if Preferences.getEditor("MiniContextMenu") != self.miniMenu:
             # regenerate context menu
@@ -4746,7 +4769,7 @@
             )
             self.menuActs["MonospacedFont"].setChecked(self.useMonospaced)
             self.menuActs["AutosaveEnable"].setChecked(
-                self.autosaveEnabled and not self.autosaveManuallyDisabled
+                self.__autosaveInterval > 0 and not self.__autosaveManuallyDisabled
             )
 
         # regenerate the margins context menu(s)
@@ -6256,21 +6279,32 @@
         Private slot handling the autosave enable context menu action.
         """
         if self.menuActs["AutosaveEnable"].isChecked():
-            self.autosaveManuallyDisabled = False
-        else:
-            self.autosaveManuallyDisabled = True
-
-    def shouldAutosave(self):
-        """
-        Public method to check the autosave flags.
+            self.__autosaveManuallyDisabled = False
+        else:
+            self.__autosaveManuallyDisabled = True
+
+    def __shouldAutosave(self):
+        """
+        Private method to check the autosave flags.
 
         @return flag indicating this editor should be saved (boolean)
         """
         return (
             bool(self.fileName)
-            and not self.autosaveManuallyDisabled
+            and not self.__autosaveManuallyDisabled
             and not self.isReadOnly()
-        )
+            and self.isModified()
+        )
+
+    def __autosave(self):
+        """
+        Private slot to save the contents of the editor automatically.
+
+        It is only saved by the autosave timer after an initial save (i.e. it already
+        has a name).
+        """
+        if self.__shouldAutosave():
+            self.saveFile()
 
     def checkSyntax(self):
         """
@@ -6837,6 +6871,8 @@
             if not (markers & (1 << self.warning)):
                 handle = self.markerAdd(line - 1, self.warning)
                 self._warnings[handle] = [warn]
+                self.syntaxerrorToggled.emit(self)
+                # signal is also used for warnings
             else:
                 for handle in self._warnings:
                     if (
@@ -6849,6 +6885,8 @@
                 if self.markerLine(handle) == line - 1:
                     del self._warnings[handle]
                     self.markerDeleteHandle(handle)
+                    self.syntaxerrorToggled.emit(self)
+                    # signal is also used for warnings
 
         self.__setAnnotation(line - 1)
         self.__markerMap.update()
@@ -7556,6 +7594,9 @@
         @param event the event object
         @type QFocusEvent
         """
+        if Preferences.getEditor("AutosaveOnFocusLost") and self.__shouldAutosave():
+            self.saveFile()
+
         self.vm.editorActGrp.setEnabled(False)
         self.setCaretWidth(0)
 

eric ide

mercurial