315 ) |
315 ) |
316 self.__markOccurrencesTimer.timeout.connect(self.__markOccurrences) |
316 self.__markOccurrencesTimer.timeout.connect(self.__markOccurrences) |
317 self.__markedText = "" |
317 self.__markedText = "" |
318 self.__searchIndicatorLines = [] |
318 self.__searchIndicatorLines = [] |
319 |
319 |
|
320 # set the autosave attributes |
|
321 self.__autosaveInterval = Preferences.getEditor("AutosaveIntervalSeconds") |
|
322 self.__autosaveManuallyDisabled = False |
|
323 |
|
324 # initialize the autosave timer |
|
325 self.__autosaveTimer = QTimer(self) |
|
326 self.__autosaveTimer.setObjectName("AutosaveTimer") |
|
327 self.__autosaveTimer.setSingleShot(True) |
|
328 self.__autosaveTimer.timeout.connect(self.__autosave) |
|
329 |
320 # initialize some spellchecking stuff |
330 # initialize some spellchecking stuff |
321 self.spell = None |
331 self.spell = None |
322 self.lastLine = 0 |
332 self.lastLine = 0 |
323 self.lastIndex = 0 |
333 self.lastIndex = 0 |
324 self.__inSpellLanguageChanged = False |
334 self.__inSpellLanguageChanged = False |
548 bnd = req.boundedTo(self.vm.size()) |
558 bnd = req.boundedTo(self.vm.size()) |
549 |
559 |
550 if bnd.width() < req.width() or bnd.height() < req.height(): |
560 if bnd.width() < req.width() or bnd.height() < req.height(): |
551 self.resize(bnd) |
561 self.resize(bnd) |
552 |
562 |
553 # set the autosave flag |
|
554 self.autosaveEnabled = Preferences.getEditor("AutosaveInterval") > 0 |
|
555 self.autosaveManuallyDisabled = False |
|
556 |
|
557 # code coverage related attributes |
563 # code coverage related attributes |
558 self.__coverageFile = "" |
564 self.__coverageFile = "" |
559 |
565 |
560 self.__initContextMenu() |
566 self.__initContextMenu() |
561 self.__initContextMenuMargins() |
567 self.__initContextMenuMargins() |
957 self.menuActs["MonospacedFont"].setChecked(self.useMonospaced) |
963 self.menuActs["MonospacedFont"].setChecked(self.useMonospaced) |
958 self.menuActs["AutosaveEnable"] = self.menu.addAction( |
964 self.menuActs["AutosaveEnable"] = self.menu.addAction( |
959 self.tr("Autosave enabled"), self.__autosaveEnable |
965 self.tr("Autosave enabled"), self.__autosaveEnable |
960 ) |
966 ) |
961 self.menuActs["AutosaveEnable"].setCheckable(True) |
967 self.menuActs["AutosaveEnable"].setCheckable(True) |
962 self.menuActs["AutosaveEnable"].setChecked(self.autosaveEnabled) |
968 self.menuActs["AutosaveEnable"].setChecked(self.__autosaveInterval > 0) |
963 self.menuActs["TypingAidsEnabled"] = self.menu.addAction( |
969 self.menuActs["TypingAidsEnabled"] = self.menu.addAction( |
964 self.tr("Typing aids enabled"), self.__toggleTypingAids |
970 self.tr("Typing aids enabled"), self.__toggleTypingAids |
965 ) |
971 ) |
966 self.menuActs["TypingAidsEnabled"].setCheckable(True) |
972 self.menuActs["TypingAidsEnabled"].setCheckable(True) |
967 self.menuActs["TypingAidsEnabled"].setEnabled(self.completer is not None) |
973 self.menuActs["TypingAidsEnabled"].setEnabled(self.completer is not None) |
2095 self.lastModified = pathlib.Path(self.fileName).stat().st_mtime |
2101 self.lastModified = pathlib.Path(self.fileName).stat().st_mtime |
2096 self.modificationStatusChanged.emit(m, self) |
2102 self.modificationStatusChanged.emit(m, self) |
2097 self.undoAvailable.emit(self.isUndoAvailable()) |
2103 self.undoAvailable.emit(self.isUndoAvailable()) |
2098 self.redoAvailable.emit(self.isRedoAvailable()) |
2104 self.redoAvailable.emit(self.isRedoAvailable()) |
2099 |
2105 |
|
2106 if not m: |
|
2107 self.__autosaveTimer.stop() |
|
2108 |
2100 @pyqtSlot(int, int) |
2109 @pyqtSlot(int, int) |
2101 def __cursorPositionChanged(self, line, index): |
2110 def __cursorPositionChanged(self, line, index): |
2102 """ |
2111 """ |
2103 Private slot to handle the cursorPositionChanged signal. |
2112 Private slot to handle the cursorPositionChanged signal. |
2104 |
2113 |
2111 @type int |
2120 @type int |
2112 """ |
2121 """ |
2113 self.cursorChanged.emit(self.fileName, line + 1, index) |
2122 self.cursorChanged.emit(self.fileName, line + 1, index) |
2114 |
2123 |
2115 if Preferences.getEditor("MarkOccurrencesEnabled"): |
2124 if Preferences.getEditor("MarkOccurrencesEnabled"): |
2116 self.__markOccurrencesTimer.stop() |
|
2117 self.__markOccurrencesTimer.start() |
2125 self.__markOccurrencesTimer.start() |
2118 |
2126 |
2119 if self.lastLine != line: |
2127 if self.lastLine != line: |
2120 self.cursorLineChanged.emit(line) |
2128 self.cursorLineChanged.emit(line) |
2121 |
2129 |
2405 @param foldPrev previous fold level (integer) |
2413 @param foldPrev previous fold level (integer) |
2406 @param token ??? |
2414 @param token ??? |
2407 @param annotationLinesAdded number of added/deleted annotation lines |
2415 @param annotationLinesAdded number of added/deleted annotation lines |
2408 (integer) |
2416 (integer) |
2409 """ |
2417 """ |
2410 if ( |
2418 if mtype & (self.SC_MOD_INSERTTEXT | self.SC_MOD_DELETETEXT): |
2411 mtype & (self.SC_MOD_INSERTTEXT | self.SC_MOD_DELETETEXT) |
2419 # 1. set/reset the autosave timer |
2412 and linesAdded != 0 |
2420 if self.__autosaveInterval > 0: |
2413 and self.breaks |
2421 self.__autosaveTimer.start(self.__autosaveInterval * 1000) |
2414 ): |
2422 |
2415 bps = [] # list of breakpoints |
2423 # 2. move breakpoints if a line was inserted or deleted |
2416 for handle, (ln, cond, temp, enabled, ignorecount) in self.breaks.items(): |
2424 if linesAdded != 0 and self.breaks: |
2417 line = self.markerLine(handle) + 1 |
2425 bps = [] # list of breakpoints |
2418 if ln != line: |
2426 for handle, ( |
2419 bps.append((ln, line)) |
2427 ln, |
2420 self.breaks[handle] = (line, cond, temp, enabled, ignorecount) |
2428 cond, |
2421 self.inLinesChanged = True |
2429 temp, |
2422 for ln, line in sorted(bps, reverse=linesAdded > 0): |
2430 enabled, |
2423 index1 = self.breakpointModel.getBreakPointIndex(self.fileName, ln) |
2431 ignorecount, |
2424 index2 = self.breakpointModel.index(index1.row(), 1) |
2432 ) in self.breaks.items(): |
2425 self.breakpointModel.setData(index2, line) |
2433 line = self.markerLine(handle) + 1 |
2426 self.inLinesChanged = False |
2434 if ln != line: |
|
2435 bps.append((ln, line)) |
|
2436 self.breaks[handle] = (line, cond, temp, enabled, ignorecount) |
|
2437 self.inLinesChanged = True |
|
2438 for ln, line in sorted(bps, reverse=linesAdded > 0): |
|
2439 index1 = self.breakpointModel.getBreakPointIndex(self.fileName, ln) |
|
2440 index2 = self.breakpointModel.index(index1.row(), 1) |
|
2441 self.breakpointModel.setData(index2, line) |
|
2442 self.inLinesChanged = False |
2427 |
2443 |
2428 def __restoreBreakpoints(self): |
2444 def __restoreBreakpoints(self): |
2429 """ |
2445 """ |
2430 Private method to restore the breakpoints. |
2446 Private method to restore the breakpoints. |
2431 """ |
2447 """ |
3638 else: |
3654 else: |
3639 fn = self.fileName |
3655 fn = self.fileName |
3640 |
3656 |
3641 self.__loadEditorConfig(fn) |
3657 self.__loadEditorConfig(fn) |
3642 self.editorAboutToBeSaved.emit(self.fileName) |
3658 self.editorAboutToBeSaved.emit(self.fileName) |
|
3659 if self.__autosaveTimer.isActive(): |
|
3660 self.__autosaveTimer.stop() |
3643 if self.writeFile(fn): |
3661 if self.writeFile(fn): |
3644 if saveas: |
3662 if saveas: |
3645 self.__clearBreakpoints(self.fileName) |
3663 self.__clearBreakpoints(self.fileName) |
3646 self.setFileName(fn) |
3664 self.setFileName(fn) |
3647 self.setModified(False) |
3665 self.setModified(False) |
4732 |
4750 |
4733 # set the calltips function |
4751 # set the calltips function |
4734 self.__setCallTips() |
4752 self.__setCallTips() |
4735 |
4753 |
4736 # set the autosave flags |
4754 # set the autosave flags |
4737 self.autosaveEnabled = Preferences.getEditor("AutosaveInterval") > 0 |
4755 self.__autosaveInterval = Preferences.getEditor("AutosaveIntervalSeconds") |
|
4756 if self.__autosaveInterval == 0: |
|
4757 self.__autosaveTimer.stop() |
|
4758 else: |
|
4759 if self.isModified(): |
|
4760 self.__autosaveTimer.start(self.__autosaveInterval * 1000) |
4738 |
4761 |
4739 if Preferences.getEditor("MiniContextMenu") != self.miniMenu: |
4762 if Preferences.getEditor("MiniContextMenu") != self.miniMenu: |
4740 # regenerate context menu |
4763 # regenerate context menu |
4741 self.__initContextMenu() |
4764 self.__initContextMenu() |
4742 else: |
4765 else: |
4744 self.menuActs["AutoCompletionEnable"].setChecked( |
4767 self.menuActs["AutoCompletionEnable"].setChecked( |
4745 self.autoCompletionThreshold() != -1 |
4768 self.autoCompletionThreshold() != -1 |
4746 ) |
4769 ) |
4747 self.menuActs["MonospacedFont"].setChecked(self.useMonospaced) |
4770 self.menuActs["MonospacedFont"].setChecked(self.useMonospaced) |
4748 self.menuActs["AutosaveEnable"].setChecked( |
4771 self.menuActs["AutosaveEnable"].setChecked( |
4749 self.autosaveEnabled and not self.autosaveManuallyDisabled |
4772 self.__autosaveInterval > 0 and not self.__autosaveManuallyDisabled |
4750 ) |
4773 ) |
4751 |
4774 |
4752 # regenerate the margins context menu(s) |
4775 # regenerate the margins context menu(s) |
4753 self.__initContextMenuMargins() |
4776 self.__initContextMenuMargins() |
4754 |
4777 |
6254 def __autosaveEnable(self): |
6277 def __autosaveEnable(self): |
6255 """ |
6278 """ |
6256 Private slot handling the autosave enable context menu action. |
6279 Private slot handling the autosave enable context menu action. |
6257 """ |
6280 """ |
6258 if self.menuActs["AutosaveEnable"].isChecked(): |
6281 if self.menuActs["AutosaveEnable"].isChecked(): |
6259 self.autosaveManuallyDisabled = False |
6282 self.__autosaveManuallyDisabled = False |
6260 else: |
6283 else: |
6261 self.autosaveManuallyDisabled = True |
6284 self.__autosaveManuallyDisabled = True |
6262 |
6285 |
6263 def shouldAutosave(self): |
6286 def __shouldAutosave(self): |
6264 """ |
6287 """ |
6265 Public method to check the autosave flags. |
6288 Private method to check the autosave flags. |
6266 |
6289 |
6267 @return flag indicating this editor should be saved (boolean) |
6290 @return flag indicating this editor should be saved (boolean) |
6268 """ |
6291 """ |
6269 return ( |
6292 return ( |
6270 bool(self.fileName) |
6293 bool(self.fileName) |
6271 and not self.autosaveManuallyDisabled |
6294 and not self.__autosaveManuallyDisabled |
6272 and not self.isReadOnly() |
6295 and not self.isReadOnly() |
6273 ) |
6296 and self.isModified() |
|
6297 ) |
|
6298 |
|
6299 def __autosave(self): |
|
6300 """ |
|
6301 Private slot to save the contents of the editor automatically. |
|
6302 |
|
6303 It is only saved by the autosave timer after an initial save (i.e. it already |
|
6304 has a name). |
|
6305 """ |
|
6306 if self.__shouldAutosave(): |
|
6307 self.saveFile() |
6274 |
6308 |
6275 def checkSyntax(self): |
6309 def checkSyntax(self): |
6276 """ |
6310 """ |
6277 Public method to perform an automatic syntax check of the file. |
6311 Public method to perform an automatic syntax check of the file. |
6278 """ |
6312 """ |
6835 warn = (msg, warningType) |
6869 warn = (msg, warningType) |
6836 markers = self.markersAtLine(line - 1) |
6870 markers = self.markersAtLine(line - 1) |
6837 if not (markers & (1 << self.warning)): |
6871 if not (markers & (1 << self.warning)): |
6838 handle = self.markerAdd(line - 1, self.warning) |
6872 handle = self.markerAdd(line - 1, self.warning) |
6839 self._warnings[handle] = [warn] |
6873 self._warnings[handle] = [warn] |
|
6874 self.syntaxerrorToggled.emit(self) |
|
6875 # signal is also used for warnings |
6840 else: |
6876 else: |
6841 for handle in self._warnings: |
6877 for handle in self._warnings: |
6842 if ( |
6878 if ( |
6843 self.markerLine(handle) == line - 1 |
6879 self.markerLine(handle) == line - 1 |
6844 and warn not in self._warnings[handle] |
6880 and warn not in self._warnings[handle] |
6847 else: |
6883 else: |
6848 for handle in list(self._warnings.keys()): |
6884 for handle in list(self._warnings.keys()): |
6849 if self.markerLine(handle) == line - 1: |
6885 if self.markerLine(handle) == line - 1: |
6850 del self._warnings[handle] |
6886 del self._warnings[handle] |
6851 self.markerDeleteHandle(handle) |
6887 self.markerDeleteHandle(handle) |
|
6888 self.syntaxerrorToggled.emit(self) |
|
6889 # signal is also used for warnings |
6852 |
6890 |
6853 self.__setAnnotation(line - 1) |
6891 self.__setAnnotation(line - 1) |
6854 self.__markerMap.update() |
6892 self.__markerMap.update() |
6855 |
6893 |
6856 def getWarningLines(self): |
6894 def getWarningLines(self): |
7554 Protected method called when the editor loses focus. |
7592 Protected method called when the editor loses focus. |
7555 |
7593 |
7556 @param event the event object |
7594 @param event the event object |
7557 @type QFocusEvent |
7595 @type QFocusEvent |
7558 """ |
7596 """ |
|
7597 if Preferences.getEditor("AutosaveOnFocusLost") and self.__shouldAutosave(): |
|
7598 self.saveFile() |
|
7599 |
7559 self.vm.editorActGrp.setEnabled(False) |
7600 self.vm.editorActGrp.setEnabled(False) |
7560 self.setCaretWidth(0) |
7601 self.setCaretWidth(0) |
7561 |
7602 |
7562 self.cancelCallTips() |
7603 self.cancelCallTips() |
7563 |
7604 |